PySSA.pyssa.presenter.main_presenter

Module for the main view presenter of the pyssa plugin.

   1#
   2# PySSA - Python-Plugin for Sequence-to-Structure Analysis
   3# Copyright (C) 2022
   4# Martin Urban (martin.urban@studmail.w-hs.de)
   5# Hannah Kullik (hannah.kullik@studmail.w-hs.de)
   6#
   7# Source code is available at <https://github.com/urban233/PySSA>
   8#
   9# This program is free software: you can redistribute it and/or modify
  10# it under the terms of the GNU General Public License as published by
  11# the Free Software Foundation, either version 3 of the License, or
  12# (at your option) any later version.
  13#
  14# This program is distributed in the hope that it will be useful,
  15# but WITHOUT ANY WARRANTY; without even the implied warranty of
  16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17# GNU General Public License for more details.
  18#
  19# You should have received a copy of the GNU General Public License
  20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21#
  22"""Module for the main view presenter of the pyssa plugin."""
  23import logging
  24import os
  25import shutil
  26import subprocess
  27import sys
  28import pathlib
  29import csv
  30
  31import numpy as np
  32import pymol
  33from typing import TYPE_CHECKING
  34from pymol import cmd
  35from PyQt5 import QtGui
  36from PyQt5 import QtWidgets
  37from PyQt5 import QtCore
  38from PyQt5.QtCore import Qt
  39
  40from pyssa.gui.ui.dialogs import dialog_settings_global
  41from pyssa.gui.ui.dialogs import dialog_help
  42from pyssa.gui.ui.dialogs import dialog_startup
  43from pyssa.gui.ui.dialogs import dialog_distance_histogram
  44from pyssa.gui.ui.dialogs import dialog_about
  45from pyssa.gui.ui.dialogs import dialog_advanced_prediction_configurations
  46from pyssa.gui.ui.dialogs import dialog_tutorial_videos
  47from pyssa.gui.ui.dialogs import dialog_rename_protein
  48from pyssa.gui.ui.messageboxes import basic_boxes
  49from pyssa.gui.ui.styles import styles
  50from pyssa.gui.ui.views import plot_view, add_protein_view
  51
  52from pyssa.internal.data_structures import protein
  53from pyssa.internal.data_structures import project
  54from pyssa.internal.data_structures import project_watcher
  55from pyssa.internal.data_structures import settings
  56from pyssa.internal.data_structures.data_classes import prediction_configuration, prediction_protein_info
  57from pyssa.internal.data_structures.data_classes import image_state
  58from pyssa.internal.data_structures.data_classes import stage
  59from pyssa.internal.data_structures.data_classes import current_session
  60from pyssa.internal.data_structures.data_classes import main_window_state
  61from pyssa.internal.data_structures.data_classes import results_state
  62from pyssa.internal.thread import task_workers, tasks
  63
  64from pyssa.io_pyssa import safeguard, filesystem_helpers
  65from pyssa.io_pyssa import filesystem_io
  66from pyssa.io_pyssa import path_util
  67
  68from pyssa.util import pyssa_keys, prediction_util
  69from pyssa.util import main_window_util
  70from pyssa.util import exit_codes
  71from pyssa.util import globals
  72from pyssa.util import session_util
  73from pyssa.util import exception
  74from pyssa.util import constants
  75from pyssa.util import input_validator
  76from pyssa.util import gui_page_management
  77from pyssa.util import tools
  78from pyssa.util import gui_utils
  79from pyssa.logging_pyssa import log_handlers
  80from pyssa.presenter import main_presenter_async
  81
  82if TYPE_CHECKING:
  83    from pyssa.gui.ui.views import main_view
  84
  85logger = logging.getLogger(__file__)
  86logger.addHandler(log_handlers.log_file_handler)
  87
  88
  89class MainPresenter:
  90    """Class for main presenter of the pyssa plugin."""
  91
  92    """
  93    The main view of the pyssa plugin.
  94    """
  95    _view: "main_view.MainView"
  96
  97    """
  98    The path to the active workspace.
  99    """
 100    _workspace_path: pathlib.Path
 101
 102    """
 103    The application settings object.
 104    """
 105    _application_settings: "settings.Settings"
 106
 107    """
 108    The currently active project.
 109    """
 110    _current_project: "project.Project"
 111
 112    """
 113    A watcher for the project state.
 114    """
 115    _project_watcher: "project_watcher.ProjectWatcher"
 116
 117    """
 118    The active task of the application.
 119    """
 120    _active_task: tasks.Task
 121
 122    def __init__(self, a_view: "main_view.MainView") -> None:
 123        """Constructor.
 124
 125        Args:
 126            a_view: the main view of the pyssa plugin.
 127
 128        Raises:
 129            IllegalArgumentException: If an argument is illegal.
 130        """
 131        # <editor-fold desc="Checks">
 132        safeguard.Safeguard.check_if_value_is_not_none(a_view, logger)
 133
 134        # </editor-fold>
 135
 136        # <editor-fold desc="Initialize class attributes">
 137        self._view = a_view
 138        self._workspace_path = constants.DEFAULT_WORKSPACE_PATH
 139        # TODO: settings and project objects get not initialized properly
 140        self._application_settings = settings.Settings("", "")
 141        self._current_project: "project.Project" = project.Project()
 142        self._project_watcher: "project_watcher.ProjectWatcher" = project_watcher.ProjectWatcher(self._current_project)
 143
 144        # </editor-fold>
 145
 146        # Check OS
 147        main_window_util.check_operating_system()
 148        # Create log dir
 149        # <editor-fold desc="Program directory check">
 150        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa"))
 151        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa/logs"))
 152        constants.PYSSA_LOGGER.info("Checked program and logs directory.")
 153
 154        # </editor-fold>
 155        # Configure settings
 156        # <editor-fold desc="Setup App Settings">
 157        self._application_settings = settings.Settings(constants.SETTINGS_DIR, constants.SETTINGS_FILENAME)
 158        if not os.path.exists(constants.SETTINGS_FULL_FILEPATH):
 159            constants.PYSSA_LOGGER.info("Settings file not found, open configuration dialog.")
 160            # Configuration dialog to setup setting file
 161            dialog = dialog_startup.DialogStartup()
 162            dialog.exec_()
 163
 164            # checks if the cancel button was pressed
 165            if dialog_startup.global_var_terminate_app == 1:
 166                os.remove(constants.SETTINGS_FULL_FILEPATH)
 167                constants.PYSSA_LOGGER.info("Configuration dialog closed, and removed new settings file.")
 168                sys.exit()
 169
 170            self._application_settings.app_launch = 1
 171            self._application_settings.workspace_path = pathlib.Path(dialog_startup.global_var_startup_workspace)
 172
 173            constants.PYSSA_LOGGER.info("Demo projects are getting downloaded and extracted ...")
 174            import zipfile
 175
 176            with zipfile.ZipFile(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"), "r") as zip_ref:
 177                zip_ref.extractall(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects"))
 178            constants.PYSSA_LOGGER.info(
 179                "Demo projects are downloaded and extracted.\n Import of demo projects started ...",
 180            )
 181
 182            path_of_demo_projects = pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects")
 183            tmp_project = project.Project("", dialog_startup.global_var_startup_workspace)
 184            for tmp_filename in os.listdir(path_of_demo_projects):
 185                try:
 186                    tmp_project = tmp_project.deserialize_project(
 187                        pathlib.Path(f"{path_of_demo_projects}/{tmp_filename}"),
 188                        self._application_settings,
 189                    )
 190                except exception.IllegalArgumentError:
 191                    constants.PYSSA_LOGGER.warning(
 192                        "The workspace path does not exist on this system, " "but this is due to the demo projects.",
 193                    )
 194                tmp_project.set_workspace_path(dialog_startup.global_var_startup_workspace)
 195                new_filepath = pathlib.Path(f"{dialog_startup.global_var_startup_workspace}/{tmp_filename}")
 196                tmp_project.serialize_project(new_filepath)
 197            constants.PYSSA_LOGGER.info("Import process of demo projects finished.")
 198            try:
 199                os.remove(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"))
 200            except FileNotFoundError:
 201                constants.PYSSA_LOGGER.warning("Zip archive of demo projects could not be found!")
 202            constants.PYSSA_LOGGER.info("Serialize settings ...")
 203            self._application_settings.serialize_settings()
 204            constants.PYSSA_LOGGER.info("Serialize settings finished.")
 205
 206            QtWidgets.QApplication.restoreOverrideCursor()
 207
 208        globals.g_settings = main_window_util.setup_app_settings(self._application_settings)
 209        self._application_settings = globals.g_settings
 210        # </editor-fold>
 211        # Check version number
 212        main_window_util.check_version_number()
 213
 214        # <editor-fold desc="Class attributes">
 215        self._workspace_path = self._application_settings.workspace_path
 216        self._workspace_status = f"Current workspace: {str(self._workspace_path)}"
 217        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
 218        self.prediction_configuration = prediction_configuration.PredictionConfiguration(True, "pdb70")
 219        self.results_name = ""
 220        self.no_of_selected_chains = 0
 221        self.plot_dialog = QtWidgets.QDialog(self._view)
 222        self.view_box = None
 223        self.block_box_expert_install = basic_boxes.no_buttons(
 224            "Local Colabfold installation",
 225            "An installation process is currently running.",
 226            QtWidgets.QMessageBox.Information,
 227        )
 228        self.prediction_type = 0
 229        self.current_session = current_session.CurrentSession("", "", "")
 230        self.is_distance_plot_open = False
 231        self.distance_plot_dialog = None
 232
 233        self.main_window_state = main_window_state.MainWindowState(
 234            results_state.ResultsState(),
 235            image_state.ImageState(),
 236        )
 237
 238        constants.PYSSA_LOGGER.info("Setup class attributes finished.")
 239        # </editor-fold>
 240
 241        # sets up the status bar
 242        self._setup_statusbar()
 243        tools.create_directory(constants.SETTINGS_DIR, "scratch")
 244        self._setup_default_configuration()
 245
 246        # if len(os.listdir(constants.LOG_PATH)) > 0:
 247        #     self.open_change_log()
 248
 249        constants.PYSSA_LOGGER.info("Setup rest of GUI related elements ...")
 250
 251        # <editor-fold desc="GUI page management">
 252        # -- Gui page management vars
 253        self.batch_analysis_management: gui_page_management.GuiPageManagement
 254        self.results_management: gui_page_management.GuiPageManagement
 255
 256        # management functions
 257        self._create_batch_analysis_management()
 258        self._create_results_management()
 259
 260        # </editor-fold>
 261
 262        # <editor-fold desc="Block box definitions">
 263        self.block_box_analysis = basic_boxes.no_buttons(
 264            "Analysis",
 265            "An analysis is currently running, please wait.",
 266            QtWidgets.QMessageBox.Information,
 267        )
 268        self.block_box_prediction: QtWidgets.QMessageBox = QtWidgets.QMessageBox()
 269        self.block_box_images = basic_boxes.no_buttons(
 270            "Analysis Images",
 271            "Images getting created, please wait.",
 272            QtWidgets.QMessageBox.Information,
 273        )
 274        self.block_box_uni = basic_boxes.no_buttons("Generic", "Generic", QtWidgets.QMessageBox.Information)
 275
 276        # </editor-fold>
 277
 278        # configure gui element properties
 279        self._view.ui.txt_results_aligned_residues.setAlignment(QtCore.Qt.AlignRight)
 280        self._view.ui.table_pred_mono_prot_to_predict.setSizeAdjustPolicy(
 281            QtWidgets.QAbstractScrollArea.AdjustToContents,
 282        )
 283        self._view.ui.table_pred_mono_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
 284        self._view.ui.table_pred_multi_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
 285        self._view.ui.list_pred_analysis_multi_ref_chains.setSelectionMode(
 286            QtWidgets.QAbstractItemView.ExtendedSelection,
 287        )
 288        self._view.ui.list_pred_analysis_multi_model_chains.setSelectionMode(
 289            QtWidgets.QAbstractItemView.ExtendedSelection,
 290        )
 291
 292        # helper attributes
 293        self.pymol_session_specs = {
 294            pyssa_keys.SESSION_SPEC_PROTEIN: [0, ""],
 295            pyssa_keys.SESSION_SPEC_COLOR: [0, ""],
 296            pyssa_keys.SESSION_SPEC_REPRESENTATION: [0, ""],
 297            pyssa_keys.SESSION_SPEC_BG_COLOR: [0, ""],
 298        }
 299
 300        # <editor-fold desc="Setup defaults for pages">
 301        self._init_fill_combo_boxes()
 302        self._init_new_page()
 303        self._init_use_page()
 304        self._init_local_pred_mono_page()
 305        self._init_local_pred_multi_page()
 306        self._init_batch_analysis_page()
 307        self._view.ui.action_toggle_notebook_visibility.setVisible(False)
 308        self._view.ui.action_settings_model_w_off_colab_notebook.setVisible(False)
 309        self.last_sidebar_button = QtWidgets.QPushButton()
 310        self._view.ui.table_pred_mono_prot_to_predict.setEditTriggers(
 311            self._view.ui.table_pred_mono_prot_to_predict.NoEditTriggers,
 312        )
 313        self._view.ui.table_pred_multi_prot_to_predict.setEditTriggers(
 314            self._view.ui.table_pred_multi_prot_to_predict.NoEditTriggers,
 315        )
 316        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEditTriggers(
 317            self._view.ui.table_pred_analysis_mono_prot_to_predict.NoEditTriggers,
 318        )
 319        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEditTriggers(
 320            self._view.ui.table_pred_analysis_multi_prot_to_predict.NoEditTriggers,
 321        )
 322
 323        # TODO: temp gui changes (need to be changed in the designer)
 324        self._view.ui.lbl_hotspots_resi_show.setText("Residue(s) as sticks")
 325        self._view.ui.lbl_hotspots_resi_hide.setText("Residue(s) as sticks")
 326
 327        # fixme: should the pdf documentation be accessible through the pyssa gui?
 328        self._view.ui.action_help_docs_pdf.setText("Documentation")
 329        self._view.ui.action_help_docs_pdf.setVisible(True)
 330        self._view.ui.action_help_docs.setText("Tutorials")
 331        self._view.ui.action_help_docs.setVisible(True)
 332
 333        if self._application_settings.wsl_install == 1 and self._application_settings.local_colabfold == 0:
 334            self._view.ui.action_install_from_file.setVisible(True)
 335        else:
 336            self._view.ui.action_install_from_file.setVisible(False)
 337        # </editor-fold>
 338
 339        self._connect_all_gui_elements()
 340
 341        self._project_watcher.show_valid_options(self._view.ui)
 342        self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
 343
 344        self.threadpool = QtCore.QThreadPool()
 345        # create scratch and cache dir
 346        try:
 347            filesystem_helpers.delete_directory(constants.SCRATCH_DIR)
 348        except Exception as e:
 349            constants.PYSSA_LOGGER.warning(f"Scratch path could not be deleted. {e}")
 350        filesystem_helpers.create_directory(constants.SCRATCH_DIR)
 351        filesystem_helpers.create_directory(constants.CACHE_DIR)
 352
 353    def start_worker_thread(self, worker_obj: object, post_process_func) -> None:  # noqa: ANN001
 354        """Sets up the worker, moves the worker to a thread and starts the thread.
 355
 356        Args:
 357            worker_obj: an object of type <work>Worker (QObject).
 358            post_process_func: a function which sould be executed if the worker is finished.
 359        """
 360        self.tmp_thread = QtCore.QThread()
 361        self.tmp_worker = worker_obj
 362        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, post_process_func)
 363        self.tmp_thread.start()
 364
 365    def _setup_statusbar(self) -> None:
 366        """Sets up the status bar and fills it with the current workspace."""
 367        self._view.setStatusBar(self._view.status_bar)
 368        self._view.status_bar.showMessage(str(self._workspace_label.text()))
 369
 370    def _setup_default_configuration(self) -> None:
 371        """Sets up the default values for specific gui elements."""
 372        self._view.ui.lbl_current_project_name.setText("")
 373        # menu
 374        # side menu
 375
 376        # new project page
 377        self._view.ui.btn_new_create_project.setEnabled(False)
 378        self._view.ui.cb_new_add_reference.setCheckable(False)
 379        self._view.ui.cb_new_add_reference.setStyleSheet("color: #E1E1E1;")
 380        # open project page
 381        self._view.ui.lbl_open_status_search.setText("")
 382        self._view.ui.btn_open_open_project.setEnabled(False)
 383        # delete project page
 384        self._view.ui.lbl_delete_status_search.setText("")
 385        self._view.ui.btn_delete_delete_project.setEnabled(False)
 386        # edit project page
 387
 388        # view project page
 389
 390        # use project page
 391
 392        # new sequence page
 393        # sequence vs .pdb page
 394        self._view.ui.btn_s_v_p_start.setEnabled(False)
 395        self._view.ui.list_s_v_p_ref_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
 396        # single analysis page
 397        self._view.ui.lbl_analysis_model_chains.hide()
 398        self._view.ui.list_analysis_model_chains.hide()
 399        self._view.ui.btn_analysis_back.hide()
 400        self._view.ui.btn_analysis_start.hide()
 401        # batch analysis page
 402
 403        # results page
 404
 405        # image page
 406
 407    def _connect_all_gui_elements(self) -> None:
 408        """Connects all gui elements with their corresponding slots."""
 409        self._view.ui.btn_info.clicked.connect(self.open_page_information)
 410
 411        # <editor-fold desc="Menu">
 412        self._view.ui.action_file_quit.triggered.connect(self.quit_app)
 413        self._view.ui.action_file_restore_settings.triggered.connect(self.restore_settings)
 414        self._view.ui.action_settings_edit_all.triggered.connect(self.open_settings_global)
 415        self._view.ui.action_help_docs.triggered.connect(self.open_tutorial)
 416        self._view.ui.action_help_docs_pdf.triggered.connect(self.open_documentation)
 417        self._view.ui.action_help_about.triggered.connect(self.open_about)
 418        self._view.ui.action_settings_open_logs.triggered.connect(self.open_logs)
 419        self._view.ui.action_settings_clear_logs.triggered.connect(self.clear_all_log_files)
 420        self._view.ui.action_help_changelog.triggered.connect(self.open_release_notes_in_standard_application)
 421        # </editor-fold>
 422
 423        # <editor-fold desc="Side Menu">
 424        self._view.ui.btn_new_page.clicked.connect(self.display_new_page)
 425        self._view.ui.btn_open_page.clicked.connect(self.display_open_page)
 426        self._view.ui.btn_delete_page.clicked.connect(self.display_delete_page)
 427        self._view.ui.btn_save_project.clicked.connect(self.save_project)
 428        self._view.ui.btn_edit_page.clicked.connect(self.display_edit_page)
 429        self._view.ui.btn_view_page.clicked.connect(self.display_view_page)
 430        self._view.ui.btn_use_page.clicked.connect(self.display_use_page)
 431        self._view.ui.btn_import_project.clicked.connect(self.import_project)
 432        self._view.ui.btn_export_project.clicked.connect(self.export_current_project)
 433        self._view.ui.btn_close_project.clicked.connect(self.close_project)
 434        self._view.ui.btn_pred_cloud_monomer_page.clicked.connect(self.display_esm_pred_mono)
 435        self._view.ui.btn_pred_local_monomer_page.clicked.connect(self.display_local_pred_mono)
 436        self._view.ui.btn_pred_local_multimer_page.clicked.connect(self.display_local_pred_multi)
 437        self._view.ui.btn_prediction_abort.clicked.connect(self.abort_prediction)
 438        self._view.ui.btn_pred_analysis_monomer_page.clicked.connect(self.display_monomer_pred_analysis)
 439        self._view.ui.btn_pred_analysis_multimer_page.clicked.connect(self.display_multimer_pred_analysis)
 440        self._view.ui.btn_batch_analysis_page.clicked.connect(self.display_job_analysis_page)
 441        self._view.ui.btn_image_analysis_page.clicked.connect(self.display_image_analysis_page)
 442        self._view.ui.btn_results_page.clicked.connect(self.display_results_page)
 443        # self._view.ui.btn_analysis_abort.clicked.connect(self.abort_analysis)
 444        self._view.ui.btn_manage_session.clicked.connect(self.display_manage_pymol_session)
 445        self._view.ui.btn_image_page.clicked.connect(self.display_image_page)
 446        self._view.ui.btn_hotspots_page.clicked.connect(self.display_hotspots_page)
 447
 448        # </editor-fold>
 449
 450        # <editor-fold desc="New project page">
 451        self._view.ui.btn_new_choose_reference.clicked.connect(self.load_reference_in_project)
 452        self._view.ui.txt_new_project_name.textChanged.connect(self.validate_project_name)
 453        self._view.ui.txt_new_choose_reference.textChanged.connect(self.validate_reference_in_project)
 454        self._view.ui.cb_new_add_reference.stateChanged.connect(self.show_add_reference)
 455        self._view.ui.btn_new_create_project.clicked.connect(self.create_new_project)
 456
 457        # </editor-fold>
 458
 459        # <editor-fold desc="Open project page">
 460        self._view.ui.btn_open_open_project.clicked.connect(self.open_project)
 461        self._view.ui.list_open_projects.doubleClicked.connect(self.open_project)
 462        self._view.ui.txt_open_search.textChanged.connect(self.validate_open_search)
 463        self._view.ui.txt_open_selected_project.textChanged.connect(self.activate_open_button)
 464        self._view.ui.list_open_projects.currentItemChanged.connect(self.select_project_from_open_list)
 465
 466        # </editor-fold>
 467
 468        # <editor-fold desc="Delete project page">
 469        self._view.ui.btn_delete_delete_project.clicked.connect(self.delete_project)
 470        self._view.ui.txt_delete_search.textChanged.connect(self.validate_delete_search)
 471        self._view.ui.txt_delete_selected_projects.textChanged.connect(self.activate_delete_button)
 472        self._view.ui.list_delete_projects.currentItemChanged.connect(self.select_project_from_delete_list)
 473
 474        # </editor-fold>
 475
 476        # <editor-fold desc="Edit project page">
 477        self._view.ui.btn_edit_page.clicked.connect(self.display_edit_page)
 478        self._view.ui.list_edit_project_proteins.currentItemChanged.connect(self.check_for_cleaning)
 479        self._view.ui.btn_edit_clean_new_prot.clicked.connect(self.clean_protein_new)
 480        self._view.ui.btn_edit_clean_update_prot.clicked.connect(self.clean_protein_update)
 481        self._view.ui.btn_edit_project_delete.clicked.connect(self.delete_protein)
 482        self._view.ui.btn_edit_existing_protein_struct.clicked.connect(self.add_existing_protein)
 483        self._view.ui.btn_edit_project_save.clicked.connect(self.save_selected_protein_structure_as_pdb_file)
 484        self._view.ui.btn_edit_protein_rename.clicked.connect(self.rename_selected_protein_structure)
 485        # </editor-fold>
 486
 487        # <editor-fold desc="View project page">
 488        self._view.ui.btn_view_project_show.clicked.connect(self.view_sequence)
 489        self._view.ui.btn_view_project_show_structure.clicked.connect(self.view_structure)
 490        self._view.ui.list_view_project_proteins.doubleClicked.connect(self.view_sequence)
 491        self._view.ui.list_view_project_proteins.itemClicked.connect(self.view_show_options)
 492        # </editor-fold>
 493
 494        # <editor-fold desc="Use project page">
 495        self._view.ui.txt_use_project_name.textChanged.connect(self.validate_use_project_name)
 496        self._view.ui.btn_use_next.clicked.connect(self.show_protein_selection_for_use)
 497        self._view.ui.txt_use_search.textChanged.connect(self.validate_use_search)
 498        self._view.ui.btn_use_add_available_protein_structures.clicked.connect(
 499            self.add_protein_structure_to_new_project,
 500        )
 501        self._view.ui.list_use_available_protein_structures.doubleClicked.connect(
 502            self.add_protein_structure_to_new_project,
 503        )
 504        self._view.ui.list_use_available_protein_structures.itemClicked.connect(self.use_enable_add)
 505        self._view.ui.btn_use_remove_selected_protein_structures.clicked.connect(
 506            self.remove_protein_structure_to_new_project,
 507        )
 508        self._view.ui.list_use_selected_protein_structures.doubleClicked.connect(
 509            self.remove_protein_structure_to_new_project,
 510        )
 511        self._view.ui.list_use_selected_protein_structures.itemClicked.connect(self.use_enable_remove)
 512        self._view.ui.btn_use_back.clicked.connect(self.hide_protein_selection_for_use)
 513        self._view.ui.btn_use_create_new_project.clicked.connect(self.pre_create_use_project)
 514
 515        # </editor-fold>
 516
 517        # <editor-fold desc="ESMFold Monomer Prediction page">
 518        self._view.ui.btn_esm_seq_to_predict.clicked.connect(self.cloud_esm_add_seq_to_predict)
 519        self._view.ui.btn_esm_seq_to_predict_remove.clicked.connect(self.cloud_esm_remove)
 520        self._view.ui.btn_esm_next.clicked.connect(self.cloud_esm_next)
 521        self._view.ui.btn_esm_back.clicked.connect(self.cloud_esm_back)
 522        self._view.ui.btn_esm_next_2.clicked.connect(self.cloud_esm_add_protein)
 523        self._view.ui.btn_esm_back_2.clicked.connect(self.cloud_esm_back_2)
 524        self._view.ui.txt_esm_prot_name.textChanged.connect(self.cloud_esm_validate_protein_name)
 525        self._view.ui.txt_esm_prot_seq.textChanged.connect(self.cloud_esm_validate_protein_sequence)
 526        self._view.ui.btn_esm_predict.clicked.connect(self.predict_esm_monomer)
 527
 528        self._view.ui.table_esm_prot_to_predict.itemSelectionChanged.connect(self.cloud_esm_item_changed)
 529        # </editor-fold>
 530
 531        # <editor-fold desc="Monomer local prediction page">
 532        self._view.ui.btn_pred_mono_seq_to_predict.clicked.connect(self.local_pred_mono_add_seq_to_predict)
 533        self._view.ui.btn_pred_mono_seq_to_predict_remove.clicked.connect(self.local_pred_mono_remove)
 534        self._view.ui.btn_pred_mono_next.clicked.connect(self.local_pred_mono_next)
 535        self._view.ui.btn_pred_mono_back.clicked.connect(self.local_pred_mono_back)
 536        self._view.ui.btn_pred_mono_add_protein.clicked.connect(self.local_pred_mono_add_protein)
 537        self._view.ui.btn_pred_mono_back_2.clicked.connect(self.local_pred_mono_back_2)
 538        self._view.ui.txt_pred_mono_prot_name.textChanged.connect(self.local_pred_mono_validate_protein_name)
 539        self._view.ui.txt_pred_mono_seq_name.textChanged.connect(self.local_pred_mono_validate_protein_sequence)
 540        self._view.ui.btn_pred_mono_advanced_config.clicked.connect(self.show_prediction_configuration)
 541        self._view.ui.btn_pred_mono_predict.clicked.connect(self.predict_local_monomer)
 542
 543        self._view.ui.table_pred_mono_prot_to_predict.itemSelectionChanged.connect(self.local_pred_mono_item_changed)
 544        # </editor-fold>
 545
 546        # <editor-fold desc="Multimer prediction page">
 547        self._view.ui.btn_pred_multi_prot_to_predict_add.clicked.connect(self.local_pred_multi_add)
 548        self._view.ui.btn_pred_multi_prot_to_predict_remove.clicked.connect(self.local_pred_multi_remove)
 549        self._view.ui.btn_pred_multi_next.clicked.connect(self.local_pred_multi_next)
 550        self._view.ui.btn_pred_multi_back.clicked.connect(self.local_pred_multi_back)
 551        self._view.ui.btn_pred_multi_prot_to_predict_add_2.clicked.connect(self.local_pred_multi_prot_to_predict_add_2)
 552        self._view.ui.btn_pred_multi_back_2.clicked.connect(self.local_pred_multi_back_2)
 553        self._view.ui.txt_pred_multi_prot_name.textChanged.connect(self.local_pred_multi_validate_protein_name)
 554        self._view.ui.txt_pred_multi_prot_seq.textChanged.connect(self.local_pred_multi_validate_protein_sequence)
 555        self._view.ui.btn_pred_multi_prot_seq_add.clicked.connect(self.local_pred_multi_add_sequence_to_list)
 556        self._view.ui.btn_pred_multi_prot_seq_overview_remove.clicked.connect(
 557            self.local_pred_multi_remove_sequence_to_list,
 558        )
 559        self._view.ui.btn_pred_multi_advanced_config.clicked.connect(self.show_prediction_configuration)
 560        self._view.ui.btn_pred_multi_predict.clicked.connect(self.predict_local_multimer)
 561
 562        self._view.ui.list_pred_multi_prot_seq_overview.itemClicked.connect(
 563            self.local_pred_multi_prot_seq_overview_item_changed,
 564        )
 565        self._view.ui.table_pred_multi_prot_to_predict.itemSelectionChanged.connect(
 566            self.local_pred_multi_prot_to_predict_item_changed,
 567        )
 568        # </editor-fold>
 569
 570        # <editor-fold desc="Monomer Prediction + Analysis page">
 571        # <editor-fold desc="Prediction section">
 572        self._view.ui.btn_pred_analysis_mono_seq_to_predict.clicked.connect(self.mono_pred_analysis_add_seq_to_predict)
 573        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.clicked.connect(
 574            self.mono_pred_analysis_remove_protein_to_predict,
 575        )
 576        self._view.ui.btn_pred_analysis_mono_next.clicked.connect(self.mono_pred_analysis_next)
 577        self._view.ui.btn_pred_analysis_mono_back.clicked.connect(self.mono_pred_analysis_back)
 578        self._view.ui.btn_pred_analysis_mono_add_protein.clicked.connect(self.mono_pred_analysis_add_protein)
 579        self._view.ui.btn_pred_analysis_mono_back_2.clicked.connect(self.mono_pred_analysis_back_2)
 580        self._view.ui.txt_pred_analysis_mono_prot_name.textChanged.connect(
 581            self.mono_pred_analysis_validate_protein_name,
 582        )
 583        self._view.ui.txt_pred_analysis_mono_seq_name.textChanged.connect(
 584            self.mono_pred_analysis_validate_protein_sequence,
 585        )
 586        self._view.ui.btn_pred_mono_advanced_config_2.clicked.connect(self.show_prediction_configuration)
 587        self._view.ui.btn_pred_analysis_mono_go_analysis_setup.clicked.connect(self.switch_monomer_pred_analysis_tab)
 588        self._view.ui.table_pred_analysis_mono_prot_to_predict.itemSelectionChanged.connect(
 589            self.mono_pred_analysis_prediction_overview_item_clicked,
 590        )
 591
 592        # </editor-fold>
 593
 594        # <editor-fold desc="Analysis section">
 595        self._view.ui.btn_pred_analysis_mono_add.clicked.connect(self.mono_pred_analysis_structure_analysis_add)
 596        self._view.ui.btn_pred_analysis_mono_remove.clicked.connect(self.remove_mono_pred_analysis_analysis_run)
 597        self._view.ui.btn_pred_analysis_mono_back_3.clicked.connect(self.mono_pred_analysis_structure_analysis_back_3)
 598        self._view.ui.btn_pred_analysis_mono_next_2.clicked.connect(self.mono_pred_analysis_structure_analysis_next_2)
 599        self._view.ui.btn_pred_analysis_mono_back_4.clicked.connect(self.mono_pred_analysis_structure_analysis_back_4)
 600        self._view.ui.btn_pred_analysis_mono_next_3.clicked.connect(self.mono_pred_analysis_structure_analysis_next_3)
 601        self._view.ui.btn_pred_analysis_mono_back_5.clicked.connect(self.mono_pred_analysis_structure_analysis_back_5)
 602        self._view.ui.btn_pred_analysis_mono_next_4.clicked.connect(self.mono_pred_analysis_structure_analysis_next_4)
 603        self._view.ui.box_pred_analysis_mono_prot_struct_1.currentIndexChanged.connect(
 604            self.check_mono_pred_analysis_if_prot_structs_are_filled,
 605        )
 606        self._view.ui.box_pred_analysis_mono_prot_struct_2.currentIndexChanged.connect(
 607            self.check_mono_pred_analysis_if_prot_structs_are_filled,
 608        )
 609        self._view.ui.list_pred_analysis_mono_ref_chains.itemSelectionChanged.connect(
 610            self.count_mono_pred_analysis_selected_chains_for_prot_struct_1,
 611        )
 612        self._view.ui.list_pred_analysis_mono_model_chains.itemSelectionChanged.connect(
 613            self.check_mono_pred_analysis_if_same_no_of_chains_selected,
 614        )
 615        self._view.ui.btn_pred_analysis_mono_back_pred_setup.clicked.connect(self.switch_monomer_pred_analysis_tab)
 616        self._view.ui.btn_pred_analysis_mono_start.clicked.connect(self.start_monomer_prediction_analysis)
 617        self._view.ui.list_pred_analysis_mono_overview.clicked.connect(
 618            self.mono_pred_analysis_structure_analysis_overview_clicked,
 619        )
 620
 621        # </editor-fold>
 622
 623        # </editor-fold>
 624
 625        # <editor-fold desc="Multimer Prediction + Analysis page">
 626        # <editor-fold desc="Prediction section">
 627        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add.clicked.connect(self.multi_pred_analysis_add)
 628        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.clicked.connect(
 629            self.multi_pred_analysis_remove_protein_to_predict,
 630        )
 631        self._view.ui.btn_pred_analysis_multi_next.clicked.connect(self.multi_pred_analysis_next)
 632        self._view.ui.btn_pred_analysis_multi_back.clicked.connect(self.multi_pred_analysis_back)
 633        self._view.ui.btn_pred_analysis_multi_prot_seq_add.clicked.connect(
 634            self.multi_pred_analysis_add_sequence_to_list,
 635        )
 636        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.clicked.connect(
 637            self.multi_pred_analysis_remove_sequence_to_list,
 638        )
 639        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.clicked.connect(
 640            self.multi_pred_analysis_add_protein_to_predict,
 641        )
 642        self._view.ui.btn_pred_analysis_multi_back_2.clicked.connect(self.multi_pred_analysis_back_2)
 643
 644        self._view.ui.txt_pred_analysis_multi_prot_name.textChanged.connect(
 645            self.multi_pred_analysis_validate_protein_name,
 646        )
 647        self._view.ui.txt_pred_analysis_multi_prot_seq.textChanged.connect(
 648            self.multi_pred_analysis_validate_protein_sequence,
 649        )
 650        self._view.ui.btn_pred_analysis_multi_advanced_config.clicked.connect(self.show_prediction_configuration)
 651        self._view.ui.btn_pred_analysis_multi_go_analysis_setup.clicked.connect(self.switch_multimer_pred_analysis_tab)
 652
 653        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clicked.connect(
 654            self.multi_pred_analysis_prot_seq_overview_item_changed,
 655        )
 656        self._view.ui.table_pred_analysis_multi_prot_to_predict.itemSelectionChanged.connect(
 657            self.multi_pred_analysis_prot_to_predict_item_changed,
 658        )
 659
 660        # </editor-fold>
 661
 662        # <editor-fold desc="Analysis section">
 663        self._view.ui.btn_pred_analysis_multi_add.clicked.connect(self.multi_pred_analysis_structure_analysis_add)
 664        self._view.ui.btn_pred_analysis_multi_remove.clicked.connect(self.remove_multi_pred_analysis_analysis_run)
 665        self._view.ui.btn_pred_analysis_multi_back_3.clicked.connect(self.multi_pred_analysis_structure_analysis_back_3)
 666        self._view.ui.btn_pred_analysis_multi_next_2.clicked.connect(self.multi_pred_analysis_structure_analysis_next_2)
 667        self._view.ui.btn_pred_analysis_multi_back_4.clicked.connect(self.multi_pred_analysis_structure_analysis_back_4)
 668        self._view.ui.btn_pred_analysis_multi_next_3.clicked.connect(self.multi_pred_analysis_structure_analysis_next_3)
 669        self._view.ui.btn_pred_analysis_multi_back_5.clicked.connect(self.multi_pred_analysis_structure_analysis_back_5)
 670        self._view.ui.btn_pred_analysis_multi_next_4.clicked.connect(self.multi_pred_analysis_structure_analysis_next_4)
 671        self._view.ui.box_pred_analysis_multi_prot_struct_1.currentIndexChanged.connect(
 672            self.check_multi_pred_analysis_if_prot_structs_are_filled,
 673        )
 674        self._view.ui.box_pred_analysis_multi_prot_struct_2.currentIndexChanged.connect(
 675            self.check_multi_pred_analysis_if_prot_structs_are_filled,
 676        )
 677        self._view.ui.list_pred_analysis_multi_ref_chains.itemSelectionChanged.connect(
 678            self.count_multi_pred_analysis_selected_chains_for_prot_struct_1,
 679        )
 680        self._view.ui.list_pred_analysis_multi_model_chains.itemSelectionChanged.connect(
 681            self.check_multi_pred_analysis_if_same_no_of_chains_selected,
 682        )
 683        self._view.ui.btn_pred_analysis_multi_back_pred_setup.clicked.connect(self.switch_multimer_pred_analysis_tab)
 684        self._view.ui.btn_pred_analysis_multi_start.clicked.connect(self.start_multimer_prediction_analysis)
 685        self._view.ui.list_pred_analysis_multi_overview.clicked.connect(
 686            self.multi_pred_analysis_structure_analysis_overview_clicked,
 687        )
 688        # </editor-fold>
 689
 690        # </editor-fold>
 691
 692        # <editor-fold desc="Structure analysis page">
 693        self._view.ui.btn_analysis_batch_add.clicked.connect(self.structure_analysis_add)
 694        self._view.ui.btn_analysis_batch_remove.clicked.connect(self.remove_analysis_run)
 695        self._view.ui.btn_analysis_batch_back.clicked.connect(self.structure_analysis_back)
 696        self._view.ui.btn_analysis_batch_next.clicked.connect(self.structure_analysis_next)
 697        self._view.ui.btn_analysis_batch_back_2.clicked.connect(self.structure_analysis_back_2)
 698        self._view.ui.btn_analysis_batch_next_2.clicked.connect(self.structure_analysis_next_2)
 699        self._view.ui.btn_analysis_batch_back_3.clicked.connect(self.structure_analysis_back_3)
 700        self._view.ui.btn_analysis_batch_next_3.clicked.connect(self.structure_analysis_next_3)
 701        self._view.ui.box_analysis_batch_prot_struct_1.currentIndexChanged.connect(
 702            self.check_if_prot_structs_are_filled_batch,
 703        )
 704        self._view.ui.box_analysis_batch_prot_struct_2.currentIndexChanged.connect(
 705            self.check_if_prot_structs_are_filled_batch,
 706        )
 707        self._view.ui.list_analysis_batch_ref_chains.itemSelectionChanged.connect(
 708            self.count_batch_selected_chains_for_prot_struct_1,
 709        )
 710        self._view.ui.list_analysis_batch_model_chains.itemSelectionChanged.connect(
 711            self.check_if_same_no_of_chains_selected_batch,
 712        )
 713        self._view.ui.btn_analysis_batch_start.clicked.connect(self.start_process_batch)
 714        self._view.ui.list_analysis_batch_overview.clicked.connect(self.structure_analysis_overview_clicked)
 715
 716        # </editor-fold>
 717
 718        # <editor-fold desc="Analysis images page">
 719        self._view.ui.btn_add_analysis_images_struct_analysis.clicked.connect(
 720            self.add_protein_pair_to_image_creation_queue,
 721        )
 722        self._view.ui.list_analysis_images_struct_analysis.doubleClicked.connect(
 723            self.add_protein_pair_to_image_creation_queue,
 724        )
 725        self._view.ui.list_analysis_images_struct_analysis.clicked.connect(self.analysis_images_enable_add)
 726        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.clicked.connect(
 727            self.remove_protein_pair_from_image_creation_queue,
 728        )
 729        self._view.ui.list_analysis_images_creation_struct_analysis.doubleClicked.connect(
 730            self.remove_protein_pair_from_image_creation_queue,
 731        )
 732        self._view.ui.list_analysis_images_creation_struct_analysis.clicked.connect(self.analysis_images_enable_remove)
 733        self._view.ui.btn_start_automatic_image_creation.clicked.connect(self.start_automatic_image_creation)
 734
 735        # </editor-fold>
 736
 737        # <editor-fold desc="Results page">
 738        self._view.ui.cb_results_analysis_options.currentIndexChanged.connect(self.load_results)
 739        self._view.ui.btn_color_rmsd.clicked.connect(self.color_protein_pair_by_rmsd)
 740        self._view.ui.btn_view_struct_alignment.clicked.connect(self.display_structure_alignment)
 741        self._view.ui.btn_view_distance_plot.clicked.connect(self.display_distance_plot)
 742        self._view.ui.btn_view_distance_histogram.clicked.connect(self.display_distance_histogram)
 743        self._view.ui.btn_view_interesting_region.clicked.connect(self.display_interesting_region)
 744        self._view.ui.btn_view_distance_table.clicked.connect(self.display_distance_table)
 745
 746        # </editor-fold>
 747
 748        # <editor-fold desc="Manage">
 749        self._view.ui.box_manage_choose_protein.activated.connect(self.choose_manage_open_protein)
 750        self._view.ui.box_manage_choose_color.activated.connect(self.choose_manage_color_selected_protein)
 751        self._view.ui.box_manage_choose_representation.activated.connect(self.choose_manage_representation)
 752        self._view.ui.box_manage_choose_bg_color.activated.connect(self.choose_manage_bg_color)
 753        self._view.ui.btn_disulfid_bond_show.clicked.connect(self.show_disulfid_bonds_as_sticks)
 754        self._view.ui.btn_disulfid_bond_hide.clicked.connect(self.hide_disulfid_bonds_as_sticks)
 755
 756        # </editor-fold>
 757
 758        # <editor-fold desc="Image page">
 759        self._view.ui.btn_update_scene.clicked.connect(self.update_scene)
 760        self._view.ui.btn_save_scene.clicked.connect(self.save_scene)
 761        self._view.ui.btn_save_image.clicked.connect(self.save_image)
 762        self._view.ui.btn_preview_image.clicked.connect(self.preview_image)
 763        self._view.ui.box_representation.activated.connect(self.show_representation)
 764        self._view.ui.box_bg_color.activated.connect(self.choose_bg_color)
 765        self._view.ui.box_renderer.activated.connect(self.choose_renderer)
 766        self._view.ui.box_ray_trace_mode.activated.connect(self.choose_ray_trace_mode)
 767        self._view.ui.box_ray_texture.activated.connect(self.choose_ray_texture)
 768        self._view.ui.cb_transparent_bg.stateChanged.connect(self.decide_transparent_bg)
 769        self._view.ui.cb_ray_tracing.stateChanged.connect(self.decide_ray_tracing)
 770
 771        # </editor-fold>
 772
 773        # <editor-fold desc="Hotspots page">
 774        self._view.ui.list_hotspots_choose_protein.currentItemChanged.connect(self.open_protein_for_hotspots)
 775        self._view.ui.btn_hotspots_resi_show.clicked.connect(self.show_resi_sticks)
 776        self._view.ui.btn_hotspots_resi_hide.clicked.connect(self.hide_resi_sticks)
 777        self._view.ui.btn_hotspots_resi_zoom.clicked.connect(self.zoom_resi_position)
 778
 779        # </editor-fold>
 780
 781    def restore_settings(self) -> None:
 782        """Restores the settings.xml file to the default values."""
 783        out = gui_utils.warning_dialog_restore_settings("Are you sure you want to restore all settings?")
 784        if out:
 785            tools.restore_default_settings(self._application_settings)
 786            self._view.status_bar.showMessage("Settings were successfully restored.")
 787            logging.info("Settings were successfully restored.")
 788        else:
 789            self._view.status_bar.showMessage("Settings were not modified.")
 790            logging.info("Settings were not modified.")
 791
 792    def quit_app(self) -> None:
 793        """Closes the entire plugin."""
 794        self._view.quit_app()
 795
 796    @staticmethod
 797    def clear_all_log_files() -> None:
 798        """Clears all log files generated under .pyssa/logs."""
 799        response = basic_boxes.yes_or_no(
 800            "Clear log files",
 801            "Are you sure you want to delete all log files?",
 802            QtWidgets.QMessageBox.Information,
 803        )
 804        if response:
 805            try:
 806                shutil.rmtree(str(constants.LOG_PATH))
 807            except PermissionError:
 808                print("The active log file was not deleted.")
 809            if len(os.listdir(str(constants.LOG_PATH))) == 1:
 810                basic_boxes.ok("Clear log files", "All log files could be deleted.", QtWidgets.QMessageBox.Information)
 811                constants.PYSSA_LOGGER.info("All log files were deleted.")
 812            else:
 813                basic_boxes.ok("Clear log files", "Not all log files could be deleted.", QtWidgets.QMessageBox.Warning)
 814                constants.PYSSA_LOGGER.warning("Not all log files were deleted!")
 815
 816    # <editor-fold desc="Open extra views">
 817    def open_settings_global(self) -> None:
 818        """Opens the dialog for the global settings."""
 819        dialog = dialog_settings_global.DialogSettingsGlobal()
 820        dialog.exec_()
 821        self._application_settings = self._application_settings.deserialize_settings()
 822        globals.g_settings = self._application_settings
 823        self._workspace_path = globals.g_settings.workspace_path
 824        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
 825        self._setup_statusbar()
 826
 827    def open_logs(self) -> None:
 828        """Opens a file explorer with all log files and can open a log file in the default application."""
 829        file_dialog = QtWidgets.QFileDialog()
 830        log_path = str(constants.LOG_PATH)
 831        file_dialog.setDirectory(log_path)
 832        file_path, _ = file_dialog.getOpenFileName(self._view, "Select a log file to open", "", "LOG File (*.log)")
 833        if file_path:
 834            os.startfile(file_path)
 835
 836    @staticmethod
 837    def open_tutorial() -> None:
 838        """Opens the official tutorial pdf file."""
 839        tmp_dialog = dialog_tutorial_videos.TutorialVideosDialog()
 840        tmp_dialog.exec_()
 841
 842    @staticmethod
 843    def open_documentation() -> None:
 844        """Opens the official plugin documentation as PDF."""
 845        os.startfile(constants.DOCS_PATH)
 846
 847    @staticmethod
 848    def open_about() -> None:
 849        """Opens the About dialog."""
 850        dialog = dialog_about.DialogAbout()
 851        dialog.exec_()
 852
 853    def open_page_information(self) -> None:
 854        """Opens the message box, to display extra information based on the page."""
 855        with open(
 856            f"{constants.PAGE_HELP_PATHS_DICT[self._view.ui.lbl_page_title.text()]}",
 857            "r",
 858            encoding="utf-8",
 859        ) as file:
 860            html_content = file.read()
 861            file.close()
 862        tmp_dialog = dialog_help.DialogHelp(html_content)
 863        tmp_dialog.exec_()
 864
 865    @staticmethod
 866    def open_release_notes_in_standard_application() -> None:
 867        """Opens the release notes in the default app."""
 868        os.startfile(constants.CHANGELOG_HTML_PATH)
 869
 870    # </editor-fold>
 871
 872    # def open_change_log(self) -> None:
 873    #     """Opens change log based on the last run pyssa version.
 874    #
 875    #     Notes:
 876    #         Change log opens only if the last pyssa version is older than the current one.
 877    #     """
 878    #     last_version = f"v{self.get_version_from_latest_log_file(self.get_filepath_of_latest_log_file())}"
 879    #     if last_version != constants.VERSION_NUMBER:
 880    #         self.open_release_notes_in_standard_application()
 881    #
 882    # def get_version_from_latest_log_file(self, a_filepath: pathlib.Path) -> str:
 883    #     """Gets the pyssa version of the latest log file.
 884    #
 885    #     Args:
 886    #         a_filepath: the filepath to the latest log file.
 887    #     """
 888    #     with open(str(a_filepath), "r", encoding="utf-8") as file:
 889    #         file_content = file.read()
 890    #         file.close()
 891    #     # Define the regex pattern to extract the version number
 892    #     pattern = r"PySSA started with version v(\d+\.\d+\.\d+)"
 893    #     # Search for the pattern in the text
 894    #     match = re.search(pattern, file_content)
 895    #     # Check if a match is found
 896    #     if match:
 897    #         version_number = match.group(1)
 898    #         print("Extracted version number:", version_number)
 899    #     else:
 900    #         print("Version number not found in the text.")
 901    #         version_number = None
 902    #     return version_number
 903    #
 904    # def get_filepath_of_latest_log_file(self) -> pathlib.Path:
 905    #     """Gets the filepath of the latest log file.
 906    #
 907    #     Raises:
 908    #         FileNotFoundError: If no log files can be found in the log directory.
 909    #     """
 910    #     # Get a list of files in the directory
 911    #     files = [f for f in os.listdir(constants.LOG_PATH) if os.path.isfile(os.path.join(constants.LOG_PATH, f))]
 912    #     # Filter files to include only log files (adjust the extension accordingly)
 913    #     log_files = [f for f in files if f.endswith(".log")]
 914    #     # Check if there are any log files
 915    #     if not log_files:
 916    #         raise FileNotFoundError("No log files found in the directory.")
 917    #     # Get the full path of each log file
 918    #     log_files_paths = [os.path.join(constants.LOG_PATH, f) for f in log_files]
 919    #     # Get the latest log file based on modification time
 920    #     latest_log_file_index = log_files_paths.index(max(log_files_paths, key=os.path.getmtime)) - 1
 921    #     return pathlib.Path(log_files_paths[latest_log_file_index])
 922
 923    # <editor-fold desc="Logic related methods">
 924
 925    # <editor-fold desc="New project page functions">
 926    def create_new_project(self) -> None:
 927        """Creates a new project with the content of the new page."""
 928        # <editor-fold desc="Checks">
 929        if self._application_settings.wsl_install == 0:
 930            basic_boxes.ok(
 931                "Create new project",
 932                "Please install local colabfold to create a project!",
 933                QtWidgets.QMessageBox.Warning,
 934            )
 935            return
 936        if self._application_settings.local_colabfold == 0:
 937            basic_boxes.ok(
 938                "Create new project",
 939                "Please install local colabfold to create a project!",
 940                QtWidgets.QMessageBox.Warning,
 941            )
 942            return
 943
 944        # </editor-fold>
 945
 946        self._view.wait_spinner.start()
 947        an_add_protein_flag: bool = False
 948        if self._view.ui.cb_new_add_reference.checkState() == 2:
 949            an_add_protein_flag = True
 950
 951        self._active_task = tasks.Task(
 952            target=main_presenter_async.create_new_project,
 953            args=(
 954                self._view.ui.txt_new_project_name.text(),
 955                self._workspace_path,
 956                an_add_protein_flag,
 957                self._view.ui.txt_new_choose_reference.text(),
 958            ),
 959            post_func=self.__await_create_new_project,
 960        )
 961        self._active_task.start()
 962        self.update_status("Creating new project ...")
 963
 964    def __await_create_new_project(self, a_result: tuple) -> None:
 965        self._current_project: "project.Project" = a_result[1]
 966        constants.PYSSA_LOGGER.info(f"Created the project {self._current_project.get_project_name()}.")
 967        self._view.ui.cb_new_add_reference.setCheckState(0)
 968        self._project_watcher.current_project = self._current_project
 969        constants.PYSSA_LOGGER.info(
 970            f"{self._project_watcher.current_project.get_project_name()} is the current project.",
 971        )
 972        self._project_watcher.on_home_page = False
 973        # update gui
 974        self._project_watcher.show_valid_options(self._view.ui)
 975        self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
 976        self.main_window_state = main_window_state.MainWindowState(
 977            results_state.ResultsState(),
 978            image_state.ImageState(),
 979        )
 980        self.display_view_page()
 981        self._view.wait_spinner.stop()
 982        self.update_status(self._workspace_status)
 983
 984    # </editor-fold>
 985
 986    # <editor-fold desc="Open project page functions">
 987    def open_project(self) -> None:
 988        """Initiates the task to open an existing project."""
 989        self._view.wait_spinner.start()
 990        self._active_task = tasks.Task(
 991            target=main_presenter_async.open_project,
 992            args=(
 993                self._workspace_path,
 994                self._view.ui.txt_open_selected_project.text(),
 995                self._application_settings,
 996            ),
 997            post_func=self.__await_open_project,
 998        )
 999        self._active_task.start()
1000        self.update_status("Opening existing project ...")
1001
1002    def __await_open_project(self, a_result: tuple) -> None:
1003        self._current_project = a_result[1]
1004        self._project_watcher.current_project = self._current_project
1005        constants.PYSSA_LOGGER.info(
1006            f"{self._project_watcher.current_project.get_project_name()} is the current project.",
1007        )
1008        self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
1009        self._project_watcher.on_home_page = False
1010        self._project_watcher.show_valid_options(self._view.ui)
1011        cmd.reinitialize()
1012        self._view.ui.btn_manage_session.hide()
1013        self.display_view_page()
1014        self.main_window_state = main_window_state.MainWindowState(
1015            results_state.ResultsState(),
1016            image_state.ImageState(),
1017        )
1018        self._view.wait_spinner.stop()
1019        self.update_status(self._workspace_status)
1020
1021    # </editor-fold>
1022
1023    # <editor-fold desc="Delete project page functions">
1024    def delete_project(self) -> None:
1025        """Deletes an existing project."""
1026        # popup message which warns the user that the selected project gets deleted
1027        response: bool = gui_utils.warning_message_project_gets_deleted()
1028        tmp_project_name = self._view.ui.txt_delete_selected_projects.text()
1029        if response is True:
1030            os.remove(pathlib.Path(f"{self._workspace_path}/{self._view.ui.txt_delete_selected_projects.text()}"))
1031            if self._view.ui.txt_delete_selected_projects.text() == self._view.ui.lbl_current_project_name.text():
1032                self._view.ui.lbl_current_project_name.clear()
1033            self._view.ui.txt_delete_selected_projects.clear()
1034            # update list
1035            self._view.ui.list_delete_projects.clear()
1036            # pre-process
1037            self._view.status_bar.showMessage(self._workspace_label.text())
1038            self._view.ui.list_delete_projects.clear()
1039            self._view.status_bar.showMessage(self._workspace_label.text())
1040            tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
1041            constants.PYSSA_LOGGER.info(f"The project {tmp_project_name} was successfully deleted.")
1042            if self._view.ui.list_delete_projects.count() == 0:
1043                self.display_home_page()
1044                self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
1045        else:
1046            constants.PYSSA_LOGGER.info("No project has been deleted. No changes were made.")
1047
1048    # </editor-fold>
1049
1050    # <editor-fold desc="Save project functions">
1051    def save_project(self) -> None:
1052        """Saves the project.xml."""
1053        self._view.wait_spinner.start()
1054        self.last_sidebar_button = styles.color_sidebar_buttons(
1055            self.last_sidebar_button,
1056            self._view.ui.btn_save_project,
1057        )
1058        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1059        self._active_task = tasks.Task(
1060            target=main_presenter_async.save_project,
1061            args=(self._current_project, 0),
1062            post_func=self.__await_save_project,
1063        )
1064        self._active_task.start()
1065        self.update_status("Saving current project ...")
1066
1067    def __await_save_project(self, result: tuple) -> None:
1068        self._view.wait_spinner.stop()
1069        self.update_status(self._workspace_status)
1070        basic_boxes.ok("Save Project", "The project was successfully saved.", QtWidgets.QMessageBox.Information)
1071
1072    # </editor-fold>
1073
1074    # <editor-fold desc="Edit project page functions">
1075    def check_for_cleaning(self) -> None:
1076        """Checks if the selected protein can be cleaned."""
1077        self._view.wait_spinner.start()
1078        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1079        try:
1080            tmp_protein_name: str = self._view.ui.list_edit_project_proteins.currentItem().text()
1081        except AttributeError:
1082            self._view.wait_spinner.stop()
1083            return
1084        self._active_task = tasks.Task(
1085            target=main_presenter_async.check_for_cleaning,
1086            args=(
1087                tmp_protein_name,
1088                self._current_project,
1089            ),
1090            post_func=self.__await_check_for_cleaning,
1091        )
1092        self._active_task.start()
1093        self.update_status("Checking protein properties ...")
1094
1095    def __await_check_for_cleaning(self, result: tuple) -> None:
1096        # check if selected protein contains any organic or solvent molecules which can be removed
1097        tmp_is_cleanable: bool = result[1]
1098        tmp_is_in_protein_pair: bool = result[2]
1099        if tmp_is_cleanable:
1100            gui_elements_to_show = [
1101                self._view.ui.lbl_edit_clean_new_prot,
1102                self._view.ui.btn_edit_clean_new_prot,
1103                self._view.ui.lbl_edit_clean_update_prot,
1104                self._view.ui.btn_edit_clean_update_prot,
1105            ]
1106            gui_utils.show_gui_elements(gui_elements_to_show)
1107        else:
1108            gui_elements_to_hide = [
1109                self._view.ui.lbl_edit_clean_new_prot,
1110                self._view.ui.btn_edit_clean_new_prot,
1111                self._view.ui.lbl_edit_clean_update_prot,
1112                self._view.ui.btn_edit_clean_update_prot,
1113            ]
1114            gui_utils.hide_gui_elements(gui_elements_to_hide)
1115        # check if selected protein is in any existing protein pair
1116        if tmp_is_in_protein_pair:
1117            gui_elements_to_hide = [
1118                self._view.ui.label_12,
1119                self._view.ui.btn_edit_project_delete,
1120            ]
1121            gui_utils.hide_gui_elements(gui_elements_to_hide)
1122        else:
1123            gui_elements_to_show = [
1124                self._view.ui.label_12,
1125                self._view.ui.btn_edit_project_delete,
1126            ]
1127            gui_utils.show_gui_elements(gui_elements_to_show)
1128        self._view.ui.btn_edit_project_save.show()
1129        self._view.ui.label_13.show()
1130        self._view.ui.label_15.show()
1131        self._view.ui.btn_edit_protein_rename.show()
1132        self._view.ui.btn_manage_session.show()
1133        self._project_watcher.show_valid_options(self._view.ui)
1134        self._view.wait_spinner.stop()
1135        self.update_status(self._workspace_status)
1136
1137    def clean_protein_new(self) -> None:
1138        """Cleans the selected protein structure and creates a new cleaned structure."""
1139        self._view.wait_spinner.start()
1140        self._active_task = tasks.Task(
1141            target=main_presenter_async.clean_protein_new,
1142            args=(
1143                self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1144                self._current_project,
1145            ),
1146            post_func=self.__await_clean_protein_new,
1147        )
1148        self._active_task.start()
1149        self.update_status("Duplicating and cleaning protein ...")
1150
1151    def __await_clean_protein_new(self, result: tuple) -> None:
1152        self._init_edit_page()
1153        self._project_watcher.show_valid_options(self._view.ui)
1154        self._view.wait_spinner.stop()
1155        self.update_status(self._workspace_status)
1156
1157    def clean_protein_update(self) -> None:
1158        """Cleans the selected protein structure."""
1159        self._view.wait_spinner.start()
1160        if basic_boxes.yes_or_no(
1161            "Clean protein",
1162            "Are you sure you want to clean this protein?\n" "This will remove all organic and solvent components!",
1163            QtWidgets.QMessageBox.Information,
1164        ):
1165            self._active_task = tasks.Task(
1166                target=main_presenter_async.clean_protein_update,
1167                args=(
1168                    self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1169                    self._current_project,
1170                ),
1171                post_func=self.__await_clean_protein_update,
1172            )
1173            self._active_task.start()
1174            self.update_status("Cleaning protein ...")
1175        else:
1176            constants.PYSSA_LOGGER.info("No protein has been cleaned.")
1177            self._view.wait_spinner.stop()
1178
1179    def __await_clean_protein_update(self) -> None:
1180        self._init_edit_page()
1181        self._project_watcher.show_valid_options(self._view.ui)
1182        self._view.wait_spinner.stop()
1183        self.update_status(self._workspace_status)
1184
1185    def delete_protein(self) -> None:
1186        """Deletes the selected protein structure."""
1187        self._view.wait_spinner.start()
1188        if gui_utils.warning_message_protein_gets_deleted():
1189            self._active_task = tasks.Task(
1190                target=main_presenter_async.delete_protein,
1191                args=(
1192                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1193                    self._current_project,
1194                ),
1195                post_func=self.__await_delete_protein,
1196            )
1197            self._active_task.start()
1198            self.update_status("Deleting protein ...")
1199        else:
1200            constants.PYSSA_LOGGER.info("No protein was deleted.")
1201            self._view.wait_spinner.stop()
1202
1203    def __await_delete_protein(self) -> None:
1204        self._init_edit_page()
1205        self._project_watcher.show_valid_options(self._view.ui)
1206        self._view.wait_spinner.stop()
1207        self.update_status(self._workspace_status)
1208
1209    def add_existing_protein(self) -> None:
1210        """Opens a dialog to adds an existing protein structure to the project."""
1211        self.tmp_dialog = view_add_protein.AddProteinView()
1212        self.tmp_dialog.return_value.connect(self.post_add_existing_protein)
1213        self.tmp_dialog.show()
1214
1215    def post_add_existing_protein(self, return_value: tuple) -> None:
1216        """Adds an existing protein structure to the current project either by id or from the filesystem.
1217
1218        Args:
1219            return_value: a tuple consisting of the filepath or PDB id and the length of the first one.
1220        """
1221        self._view.wait_spinner.start()
1222        if return_value[1] > 0:
1223            self._active_task = tasks.Task(
1224                target=main_presenter_async.add_existing_protein_to_project,
1225                args=(return_value, self._current_project),
1226                post_func=self.__await_post_add_existing_protein,
1227            )
1228            self._active_task.start()
1229            self.update_status("Adding protein to current project ...")
1230        else:
1231            self._view.wait_spinner.stop()
1232            self.display_edit_page()
1233
1234    def __await_post_add_existing_protein(self, result: tuple) -> None:
1235        self._current_project = result[1]
1236        self._project_watcher.show_valid_options(self._view.ui)
1237        self._view.wait_spinner.stop()
1238        self.update_status(self._workspace_status)
1239        self.display_edit_page()
1240
1241    def save_selected_protein_structure_as_pdb_file(self) -> None:
1242        """Saves selected protein as pdb file."""
1243        self._view.wait_spinner.start()
1244        file_dialog = QtWidgets.QFileDialog()
1245        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1246        file_dialog.setDirectory(desktop_path)
1247        file_path, _ = file_dialog.getSaveFileName(
1248            self._view,
1249            "Save protein structure",
1250            "",
1251            "Protein Data Bank File (*.pdb)",
1252        )
1253        if file_path:
1254            self._active_task = tasks.Task(
1255                target=main_presenter_async.save_selected_protein_structure_as_pdb_file,
1256                args=(self._view.ui.list_edit_project_proteins.currentItem().text(), self._current_project, file_path),
1257                post_func=self.__await_save_selected_protein_structure_as_pdb_file,
1258            )
1259            self._active_task.start()
1260        else:
1261            self._view.wait_spinner.stop()
1262
1263    def __await_save_selected_protein_structure_as_pdb_file(self, result: tuple) -> None:
1264        self._view.wait_spinner.stop()
1265        if result[0] == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1266            basic_boxes.ok(
1267                "Save protein structure",
1268                "Saving the protein as .pdb file failed!",
1269                QtWidgets.QMessageBox.Error,
1270            )
1271        elif result[0] == exit_codes.EXIT_CODE_ZERO[0]:
1272            basic_boxes.ok(
1273                "Save protein structure",
1274                "The protein was successfully saved as .pdb file.",
1275                QtWidgets.QMessageBox.Information,
1276            )
1277        else:
1278            basic_boxes.ok(
1279                "Save protein structure",
1280                "Saving the protein as .pdb file failed with an unexpected error!",
1281                QtWidgets.QMessageBox.Error,
1282            )
1283        self._project_watcher.show_valid_options(self._view.ui)
1284        self.update_status(self._workspace_status)
1285
1286    def rename_selected_protein_structure(self) -> None:
1287        """Opens a new view to rename the selected protein."""
1288        self._view.wait_spinner.start()
1289        self.tmp_dialog = dialog_rename_protein.DialogRenameProtein(self._workspace_path)
1290        self.tmp_dialog.return_value.connect(self.post_rename_selected_protein_structure)
1291        self.tmp_dialog.show()
1292
1293    def post_rename_selected_protein_structure(self, return_value: tuple) -> None:
1294        """Renames a selected protein structure."""
1295        if return_value[1] is True:
1296            self._active_task = tasks.Task(
1297                target=main_presenter_async.rename_selected_protein_structure,
1298                args=(
1299                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1300                    return_value[0],
1301                    self._current_project,
1302                ),
1303                post_func=self.__await_post_rename_selected_protein_structure,
1304            )
1305            self._active_task.start()
1306        else:
1307            self._view.wait_spinner.stop()
1308
1309    def __await_post_rename_selected_protein_structure(self, result: tuple) -> None:
1310        self._init_edit_page()
1311        self._project_watcher.show_valid_options(self._view.ui)
1312        self._view.wait_spinner.stop()
1313
1314    # </editor-fold>
1315
1316    # <editor-fold desc="View project page functions">
1317    def view_structure(self) -> None:
1318        """Displays the structure of the selected protein in pymol."""
1319        protein_name = self._view.ui.list_view_project_proteins.currentItem().text()
1320        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1321        cmd.reinitialize()
1322        self._view.ui.btn_manage_session.show()
1323        try:
1324            self._current_project.search_protein(protein_name).load_protein_pymol_session()
1325            constants.PYSSA_LOGGER.info("Loaded PyMOL session of protein %s", protein_name)
1326        except pymol.CmdException:
1327            constants.PYSSA_LOGGER.error("Error while loading protein in PyMOL!")
1328            return
1329        self.current_session = current_session.CurrentSession(
1330            "protein",
1331            protein_name,
1332            self._current_project.search_protein(protein_name).pymol_session,
1333        )
1334        print(self.current_session)
1335
1336    # </editor-fold>
1337
1338    # <editor-fold desc="Use project page functions">
1339    def display_use_page(self) -> None:
1340        """Displays the use project page."""
1341        self._view.wait_spinner.start()
1342        if self.is_distance_plot_open:
1343            self.distance_plot_dialog.close()
1344            self.is_distance_plot_open = False
1345
1346        self.start_worker_thread(
1347            task_workers.LoadUsePageWorker(
1348                self._workspace_path,
1349                self._current_project.convert_list_of_proteins_to_list_of_protein_infos(),
1350            ),
1351            self.post_display_use_page,
1352        )
1353        self._init_use_page()
1354
1355    def post_display_use_page(self, return_value) -> None:  # noqa: ANN001
1356        """Displays the use project page, after cpu intense task (post thread method).
1357
1358        Args:
1359            return_value: the value which gets returned from the thread process
1360        """
1361        # this for-loop is necessary for eliminating all proteins which are in the current project from the ones which
1362        # are available
1363        for tmp_item in return_value[0]:
1364            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1365        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1366            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1367            tmp_prot_name = self._view.ui.list_use_selected_protein_structures.currentItem().text()
1368            if tmp_prot_name in return_value[1]:
1369                return_value[1].remove(tmp_prot_name)
1370
1371        for tmp_item in return_value[1]:
1372            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1373        for tmp_project_name in return_value[2]:
1374            self._view.ui.list_use_existing_projects.addItem(QtWidgets.QListWidgetItem(tmp_project_name))
1375
1376        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 14, "Use existing project")
1377        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_use_page)
1378        self._view.wait_spinner.stop()
1379
1380    def pre_create_use_project(self) -> None:
1381        """Sets up the worker for the create_use_project task."""
1382        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
1383        # copy proteins in new project
1384        proteins_to_copy = []
1385        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1386            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1387            proteins_to_copy.append(self._view.ui.list_use_selected_protein_structures.currentItem().text())
1388
1389        # <editor-fold desc="Worker setup">
1390        # --Begin: worker setup
1391        self.tmp_thread = QtCore.QThread()
1392        self.tmp_worker = task_workers.CreateUseProjectWorker(self._workspace_path, proteins_to_copy)
1393        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.create_use_project)
1394        self.tmp_thread.start()
1395        # --End: worker setup
1396
1397        # </editor-fold>
1398
1399        self._view.ui.lbl_current_project_name.setText(self._view.ui.txt_use_project_name.text())
1400        self._view.status_bar.showMessage(f"Creating new project: {self._view.ui.txt_use_project_name.text()} ...")
1401        # save project folder in current workspace
1402        new_project = project.Project(self._view.ui.txt_use_project_name.text(), self._workspace_path)
1403        # new_project.create_project_tree()
1404        self._current_project = new_project
1405
1406    def create_use_project(self, proteins_for_new_project) -> None:  # noqa: ANN001
1407        """Post thread method.
1408
1409        Args:
1410            proteins_for_new_project (list): the proteins which are in the new project
1411        """
1412        for tmp_protein_obj in proteins_for_new_project:
1413            self._current_project.add_existing_protein(tmp_protein_obj)
1414        self._current_project.serialize_project(
1415            pathlib.Path(f"{self._workspace_path}/{self._current_project.get_project_name()}.xml"),
1416        )
1417        # shows options which can be done with the data in the project folder
1418        self._project_watcher.current_project = self._current_project
1419        self._project_watcher.on_home_page = False
1420        self._project_watcher.show_valid_options(self._view.ui)
1421        self.project_scanner.project = self._current_project
1422        self._init_use_page()
1423        constants.PYSSA_LOGGER.info(
1424            f"The project {self._current_project.get_project_name()} was successfully created through a use.",
1425        )
1426        self.display_view_page()
1427        QtWidgets.QApplication.restoreOverrideCursor()
1428
1429    # </editor-fold>
1430
1431    # <editor-fold desc="Import, Export functions">
1432    def import_project(self) -> None:
1433        """Imports a project.xml into the current workspace."""
1434        self.last_sidebar_button = styles.color_sidebar_buttons(
1435            self.last_sidebar_button,
1436            self._view.ui.btn_import_project,
1437        )
1438        file_dialog = QtWidgets.QFileDialog()
1439        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1440        file_dialog.setDirectory(desktop_path)
1441        file_path, _ = file_dialog.getOpenFileName(
1442            self._view,
1443            "Select a project file to import",
1444            "",
1445            "XML Files (*.xml)",
1446        )
1447        if file_path:
1448            tmp_project = project.Project("", self._workspace_path)
1449            tmp_project = tmp_project.deserialize_project(pathlib.Path(file_path), self._application_settings)
1450            tmp_project.set_workspace_path(self._workspace_path)
1451            if len(tmp_project.proteins) <= 1:
1452                if self._application_settings.wsl_install == 0:
1453                    basic_boxes.ok(
1454                        "Create new project",
1455                        "Please install local colabfold to import this project!",
1456                        QtWidgets.QMessageBox.Warning,
1457                    )
1458                    return
1459                elif self._application_settings.local_colabfold == 0:  # noqa: RET505
1460                    basic_boxes.ok(
1461                        "Create new project",
1462                        "Please install local colabfold to import this project!",
1463                        QtWidgets.QMessageBox.Warning,
1464                    )
1465                    return
1466            new_filepath = pathlib.Path(f"{self._workspace_path}/{tmp_project.get_project_name()}.xml")
1467            tmp_project.serialize_project(new_filepath)
1468            self._current_project = self._current_project.deserialize_project(new_filepath, self._application_settings)
1469            constants.PYSSA_LOGGER.info(f"Opening the project {self._current_project.get_project_name()}.")
1470            self._project_watcher.current_project = self._current_project
1471            self.project_scanner.project = self._current_project
1472            constants.PYSSA_LOGGER.info(
1473                f"{self._project_watcher.current_project.get_project_name()} is the current project.",
1474            )
1475            self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
1476            self._project_watcher.on_home_page = False
1477            self._project_watcher.show_valid_options(self._view.ui)
1478            self._view.ui.btn_manage_session.show()
1479            self.display_view_page()
1480            basic_boxes.ok(
1481                "Import Project",
1482                "The project was successfully imported.",
1483                QtWidgets.QMessageBox.Information,
1484            )
1485
1486    def export_current_project(self) -> None:
1487        """Exports the current project to an importable format."""
1488        if self.is_distance_plot_open:
1489            self.distance_plot_dialog.close()
1490            self.is_distance_plot_open = False
1491        self.last_sidebar_button = styles.color_sidebar_buttons(
1492            self.last_sidebar_button,
1493            self._view.ui.btn_export_project,
1494        )
1495        file_dialog = QtWidgets.QFileDialog()
1496        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1497        file_dialog.setDirectory(desktop_path)
1498        file_path, _ = file_dialog.getSaveFileName(self._view, "Save current project", "", "XML Files (*.xml)")
1499        if file_path:
1500            self._current_project.serialize_project(pathlib.Path(file_path))
1501            basic_boxes.ok(
1502                "Export Project",
1503                "The project was successfully exported.",
1504                QtWidgets.QMessageBox.Information,
1505            )
1506
1507    # </editor-fold>
1508
1509    # <editor-fold desc="Close project functions">
1510    def close_project(self) -> None:
1511        """Closes the current project."""
1512        if self.is_distance_plot_open:
1513            self.distance_plot_dialog.close()
1514            self.is_distance_plot_open = False
1515        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1516        cmd.reinitialize()
1517        self._view.ui.list_hotspots_choose_protein.clear()
1518        self._project_watcher.on_home_page = True
1519        self._project_watcher.current_project = project.Project("", pathlib.Path(""))
1520        self._project_watcher.show_valid_options(self._view.ui)
1521        self._view.ui.lbl_current_project_name.setText("")
1522        self._init_all_pages()
1523        self.results_name = ""
1524        constants.PYSSA_LOGGER.info(f"The project {self._current_project.get_project_name()} was closed")
1525        self.display_home_page()
1526
1527    # </editor-fold>
1528
1529    # <editor-fold desc="ESMFold Monomer functions">
1530    def post_predict_esm_monomer(self, output) -> None:  # noqa: ANN001
1531        """Post thread method, for the prediction process.
1532
1533        Args:
1534            output (list): the proteins which got predicted
1535        """
1536        self.block_box_prediction.destroy(True)
1537        for tmp_filename in os.listdir(constants.ESMFOLD_PDB_DIR):
1538            constants.PYSSA_LOGGER.info(
1539                f"Add protein {tmp_filename} to the current project {self._current_project.get_project_name()}",
1540            )
1541            self._current_project.add_existing_protein(
1542                protein.Protein(
1543                    tmp_filename.replace(".pdb", ""),
1544                    path_util.FilePath(pathlib.Path(f"{constants.ESMFOLD_PDB_DIR}/{tmp_filename}")),
1545                ),
1546            )
1547        if len(output) > 0:
1548            formatted_output = ", ".join(output)
1549            basic_boxes.ok(
1550                "ESMFold Prediction",
1551                f"These protein prediction failed: {formatted_output}.",
1552                QtWidgets.QMessageBox.Critical,
1553            )
1554        else:
1555            basic_boxes.ok("ESMFold Prediction", "The prediction was successful.", QtWidgets.QMessageBox.Information)
1556        self._current_project.serialize_project(self._current_project.get_project_xml_path())
1557        self.display_view_page()
1558        self._project_watcher.show_valid_options(self._view.ui)
1559
1560    def predict_esm_monomer(self) -> None:
1561        """Sets up the worker to predict the proteins with the ESM-Fold."""
1562        # <editor-fold desc="Worker setup">
1563        # --Begin: worker setup
1564        self.tmp_thread = QtCore.QThread()
1565        self.tmp_worker = task_workers.EsmFoldWorker(self._view.ui.table_esm_prot_to_predict)
1566        self.tmp_thread = task_workers.setup_worker_for_work(
1567            self.tmp_thread,
1568            self.tmp_worker,
1569            self.post_predict_esm_monomer,
1570        )
1571        self.tmp_thread.start()
1572        # --End: worker setup
1573
1574        # </editor-fold>
1575
1576        self.block_box_prediction = QtWidgets.QMessageBox()
1577        self.block_box_prediction = gui_utils.setup_standard_block_box(
1578            self.block_box_prediction,
1579            "Structure Prediction",
1580            "A prediction is currently running.",
1581        )
1582        # self.block_box_prediction.setStandardButtons(QtWidgets.QMessageBox.NoButton)
1583        # self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1584        # self.block_box_prediction.setWindowIcon(
1585        #     PyQt5.constants.PLUGIN_LOGO_ICON_OBJ)
1586        # styles.set_stylesheet(self.block_box_prediction)
1587        # self.block_box_prediction.setWindowTitle("Structure Prediction")
1588        # self.block_box_prediction.setText("A prediction is currently running.")
1589        self.block_box_prediction.exec_()
1590
1591    # </editor-fold>
1592
1593    # <editor-fold desc="Monomer Local Prediction functions">
1594    def post_prediction_process(self, an_exit_code: int, an_exit_code_description: str) -> None:
1595        """Process which runs after each prediction job."""
1596        if an_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1597            self.block_box_prediction.destroy(True)
1598            basic_boxes.ok(
1599                "Prediction",
1600                "Prediction failed because there was an error writing the fasta file(s)!",
1601                QtWidgets.QMessageBox.Critical,
1602            )
1603            self.display_view_page()
1604            self._project_watcher.show_valid_options(self._view.ui)
1605            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1606        elif an_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
1607            self.block_box_prediction.destroy(True)
1608            basic_boxes.ok(
1609                "Prediction",
1610                "Prediction failed because the fasta file(s) could not be found!",
1611                QtWidgets.QMessageBox.Critical,
1612            )
1613            self.display_view_page()
1614            self._project_watcher.show_valid_options(self._view.ui)
1615            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1616        elif an_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
1617            self.block_box_prediction.destroy(True)
1618            basic_boxes.ok(
1619                "Prediction",
1620                "Prediction failed because a subprocess failed!",
1621                QtWidgets.QMessageBox.Critical,
1622            )
1623            self.display_view_page()
1624            self._project_watcher.show_valid_options(self._view.ui)
1625            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1626        elif an_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1627            self.block_box_prediction.destroy(True)
1628            basic_boxes.ok(
1629                "Prediction",
1630                "Prediction failed because of an unknown error!",
1631                QtWidgets.QMessageBox.Critical,
1632            )
1633            self.display_view_page()
1634            self._project_watcher.show_valid_options(self._view.ui)
1635            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1636        elif an_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1637            # Prediction was successful
1638            if self.prediction_type == constants.PREDICTION_TYPE_PRED:
1639                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1640                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1641                self.block_box_prediction.destroy(True)
1642                basic_boxes.ok(
1643                    "Structure prediction",
1644                    "All structure predictions are done. Go to View to check the new proteins.",
1645                    QtWidgets.QMessageBox.Information,
1646                )
1647                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1648                self._project_watcher.show_valid_options(self._view.ui)
1649                self._init_local_pred_mono_page()
1650                self._init_local_pred_multi_page()
1651                self.display_view_page()
1652            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS:
1653                # executes if monomers were successfully predicted
1654                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1655                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1656                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1657                constants.PYSSA_LOGGER.info("Begin analysis process.")
1658                constants.PYSSA_LOGGER.debug(
1659                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1660                )
1661
1662                # self.worker_analysis = workers.AnalysisWorkerPool(
1663                #    self._view.ui.list_pred_analysis_mono_overview, self._view.ui.cb_pred_analysis_mono_images,
1664                #    self._view.status_bar, self._current_project, self._application_settings, self._init_mono_pred_analysis_page)
1665                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1666                # self.threadpool.start(self.worker_analysis)
1667                constants.PYSSA_LOGGER.debug(
1668                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1669                )
1670
1671                # <editor-fold desc="Worker setup">
1672                # TODO: test code below
1673                # --Begin: worker setup
1674                self.tmp_thread = QtCore.QThread()
1675                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1676                    self._view.ui.list_pred_analysis_mono_overview,
1677                    self._view.ui.cb_pred_analysis_mono_images,
1678                    self._view.status_bar,
1679                    self._current_project,
1680                    self._application_settings,
1681                    self._init_mono_pred_analysis_page,
1682                )
1683                self.tmp_thread = task_workers.setup_worker_for_work(
1684                    self.tmp_thread,
1685                    self.tmp_worker,
1686                    self.display_view_page,
1687                )
1688                self.tmp_worker.finished.connect(self.post_analysis_process)
1689                self.tmp_thread.start()
1690                # --End: worker setup
1691
1692                # </editor-fold>
1693
1694                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1695                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1696                self.block_box_prediction.destroy(True)
1697                self.block_box_analysis.exec_()
1698                self.display_view_page()
1699                self._project_watcher.show_valid_options(self._view.ui)
1700            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS:
1701                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1702                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1703                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1704                constants.PYSSA_LOGGER.info("Begin analysis process.")
1705                constants.PYSSA_LOGGER.debug(
1706                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1707                )
1708
1709                # self.worker_analysis = workers.AnalysisWorkerPool(
1710                #    self._view.ui.list_pred_analysis_multi_overview, self._view.ui.cb_pred_analysis_multi_images,
1711                #    self._view.status_bar, self._current_project, self._application_settings, self._init_multi_pred_analysis_page)
1712                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1713                # self.threadpool.start(self.worker_analysis)
1714                constants.PYSSA_LOGGER.debug(
1715                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1716                )
1717
1718                # <editor-fold desc="Worker setup">
1719                # TODO: test code below
1720                # --Begin: worker setup
1721                self.tmp_thread = QtCore.QThread()
1722                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1723                    self._view.ui.list_pred_analysis_multi_overview,
1724                    self._view.ui.cb_pred_analysis_multi_images,
1725                    self._view.status_bar,
1726                    self._current_project,
1727                    self._application_settings,
1728                    self._init_multi_pred_analysis_page,
1729                )
1730                self.tmp_thread = task_workers.setup_worker_for_work(
1731                    self.tmp_thread,
1732                    self.tmp_worker,
1733                    self.display_view_page,
1734                )
1735                self.tmp_worker.finished.connect(self.post_analysis_process)
1736                self.tmp_thread.start()
1737                # --End: worker setup
1738
1739                # </editor-fold>
1740
1741                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1742                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1743                self.block_box_prediction.destroy(True)
1744                self.block_box_analysis.exec_()
1745                self.display_view_page()
1746                self._project_watcher.show_valid_options(self._view.ui)
1747        try:
1748            shutil.rmtree(pathlib.Path(f"{constants.SCRATCH_DIR}/local_predictions"))
1749        except Exception as e:
1750            constants.PYSSA_LOGGER.warning(f"Local predictions scratch path could not be deleted. {e}")
1751
1752    def predict_local_monomer(self) -> None:
1753        """Sets tup the worker for the prediction with the colabfold."""
1754        self._view.wait_spinner.start()
1755        self.prediction_type = constants.PREDICTION_TYPE_PRED
1756        constants.PYSSA_LOGGER.info("Begin prediction process.")
1757        self.update_status("Begin prediction process ...")
1758        predictions: list[
1759            prediction_protein_info.PredictionProteinInfo
1760        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_mono_prot_to_predict)
1761
1762        self._active_task = tasks.Task(
1763            target=main_presenter_async.predict_protein_with_colabfold,
1764            args=(
1765                predictions,
1766                self.prediction_configuration,
1767                self._current_project,
1768            ),
1769            post_func=self.__await_predict_protein_with_colabfold,
1770        )
1771        self._active_task.start()
1772
1773        self.block_box_prediction = QtWidgets.QMessageBox()
1774        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1775        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1776        styles.set_stylesheet(self.block_box_prediction)
1777        self.block_box_prediction.setWindowTitle("Structure Prediction")
1778        self.block_box_prediction.setText("A prediction is currently running.")
1779        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1780        self.block_box_prediction.exec_()
1781        if self.block_box_prediction.clickedButton() == btn_abort:
1782            self.abort_prediction()
1783            self.block_box_prediction.close()
1784            self._view.wait_spinner.stop()
1785            return
1786        else:  # noqa: RET505
1787            self.block_box_prediction.close()
1788            self._view.wait_spinner.stop()
1789
1790    def __await_predict_protein_with_colabfold(self, result: tuple) -> None:
1791        """Process which runs after each prediction job."""
1792        tmp_exit_code = result[0]
1793        tmp_exit_code_description = [1]
1794        if tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1795            self.block_box_prediction.destroy(True)
1796            basic_boxes.ok(
1797                "Prediction",
1798                "Prediction failed because there was an error writing the fasta file(s)!",
1799                QtWidgets.QMessageBox.Critical,
1800            )
1801            self.display_view_page()
1802            self._project_watcher.show_valid_options(self._view.ui)
1803            constants.PYSSA_LOGGER.error(
1804                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1805            )
1806        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
1807            self.block_box_prediction.destroy(True)
1808            basic_boxes.ok(
1809                "Prediction",
1810                "Prediction failed because the fasta file(s) could not be found!",
1811                QtWidgets.QMessageBox.Critical,
1812            )
1813            self.display_view_page()
1814            self._project_watcher.show_valid_options(self._view.ui)
1815            constants.PYSSA_LOGGER.error(
1816                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1817            )
1818        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
1819            self.block_box_prediction.destroy(True)
1820            basic_boxes.ok(
1821                "Prediction",
1822                "Prediction failed because a subprocess failed!",
1823                QtWidgets.QMessageBox.Critical,
1824            )
1825            self.display_view_page()
1826            self._project_watcher.show_valid_options(self._view.ui)
1827            constants.PYSSA_LOGGER.error(
1828                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1829            )
1830        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1831            self.block_box_prediction.destroy(True)
1832            basic_boxes.ok(
1833                "Prediction",
1834                "Prediction failed because of an unknown error!",
1835                QtWidgets.QMessageBox.Critical,
1836            )
1837            self.display_view_page()
1838            self._project_watcher.show_valid_options(self._view.ui)
1839            constants.PYSSA_LOGGER.error(
1840                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1841            )
1842        elif tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1843            # Prediction was successful
1844            if self.prediction_type == constants.PREDICTION_TYPE_PRED:
1845                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1846                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1847                self.block_box_prediction.destroy(True)
1848                basic_boxes.ok(
1849                    "Structure prediction",
1850                    "All structure predictions are done. Go to View to check the new proteins.",
1851                    QtWidgets.QMessageBox.Information,
1852                )
1853                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1854                self._project_watcher.show_valid_options(self._view.ui)
1855                self._init_local_pred_mono_page()
1856                self._init_local_pred_multi_page()
1857                self.display_view_page()
1858        self._view.wait_spinner.stop()
1859
1860    def abort_prediction(self) -> None:
1861        """Aborts the running prediction."""
1862        constants.PYSSA_LOGGER.info("Structure prediction process was aborted manually.")
1863        subprocess.run(["wsl", "--shutdown"])
1864        constants.PYSSA_LOGGER.info("Shutdown of wsl environment.")
1865        filesystem_io.FilesystemCleaner.clean_prediction_scratch_folder()
1866        constants.PYSSA_LOGGER.info("Cleaned scratch directory.")
1867        basic_boxes.ok("Abort prediction", "The structure prediction was aborted.", QtWidgets.QMessageBox.Information)
1868        self.last_sidebar_button = styles.color_sidebar_buttons(
1869            self.last_sidebar_button,
1870            self._view.ui.btn_prediction_abort,
1871        )
1872        self._project_watcher.show_valid_options(self._view.ui)
1873
1874    # </editor-fold>
1875
1876    # <editor-fold desc="Multimer Local Prediction functions">
1877    def predict_local_multimer(self) -> None:
1878        """Sets up the worker for the prediction with the colabfold."""
1879        self._view.wait_spinner.start()
1880        self.prediction_type = constants.PREDICTION_TYPE_PRED
1881        constants.PYSSA_LOGGER.info("Begin multimer prediction process.")
1882        self.update_status("Begin prediction process ...")
1883        predictions: list[
1884            prediction_protein_info.PredictionProteinInfo
1885        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_multi_prot_to_predict)
1886
1887        self._active_task = tasks.Task(
1888            target=main_presenter_async.predict_protein_with_colabfold,
1889            args=(
1890                predictions,
1891                self.prediction_configuration,
1892                self._current_project,
1893            ),
1894            post_func=self.__await_predict_protein_with_colabfold,
1895        )
1896        self._active_task.start()
1897
1898        self.block_box_prediction = QtWidgets.QMessageBox()
1899        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1900        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1901        styles.set_stylesheet(self.block_box_prediction)
1902        self.block_box_prediction.setWindowTitle("Structure Prediction")
1903        self.block_box_prediction.setText("A prediction is currently running.")
1904        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1905        self.block_box_prediction.exec_()
1906        if self.block_box_prediction.clickedButton() == btn_abort:
1907            self.abort_prediction()
1908            self.block_box_prediction.close()
1909            self._view.wait_spinner.stop()
1910        else:
1911            self.block_box_prediction.close()
1912            self._view.wait_spinner.stop()
1913
1914    # </editor-fold>
1915
1916    # <editor-fold desc="Monomer Prediction + Analysis functions">
1917    def start_monomer_prediction_analysis(self) -> None:
1918        """Sets up the worker for the prediction of the proteins."""
1919        self._view.wait_spinner.start()
1920        self.prediction_type = constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS
1921        constants.PYSSA_LOGGER.info("Begin prediction process.")
1922        self.update_status("Begin prediction process ...")
1923        predictions: list[
1924            prediction_protein_info.PredictionProteinInfo
1925        ] = prediction_util.get_prediction_name_and_seq_from_table(
1926            self._view.ui.table_pred_analysis_mono_prot_to_predict,
1927        )
1928
1929        self._active_task = tasks.Task(
1930            target=main_presenter_async.predict_protein_with_colabfold,
1931            args=(
1932                predictions,
1933                self.prediction_configuration,
1934                self._current_project,
1935            ),
1936            post_func=self.__await_monomer_prediction_for_subsequent_analysis,
1937        )
1938        self._active_task.start()
1939
1940        self.block_box_prediction = QtWidgets.QMessageBox()
1941        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1942        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1943        styles.set_stylesheet(self.block_box_prediction)
1944        self.block_box_prediction.setWindowTitle("Structure Prediction")
1945        self.block_box_prediction.setText("A prediction is currently running.")
1946        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1947        self.block_box_prediction.exec_()
1948        if self.block_box_prediction.clickedButton() == btn_abort:
1949            self.abort_prediction()
1950            self.block_box_prediction.close()
1951            self._view.wait_spinner.stop()
1952        else:
1953            self.block_box_prediction.close()
1954            self._view.wait_spinner.stop()
1955
1956    def __await_monomer_prediction_for_subsequent_analysis(self, result: tuple) -> None:
1957        tmp_exit_code = result[0]
1958        tmp_exit_code_description = [1]
1959        if tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1960            # Prediction was successful
1961            self.block_box_prediction.destroy(True)
1962            constants.PYSSA_LOGGER.info("All structure predictions are done.")
1963            self.update_status("All structure predictions are done.")
1964            constants.PYSSA_LOGGER.info("Begin analysis process.")
1965            self.update_status("Begin analysis process ...")
1966
1967            tmp_raw_analysis_run_names: list = []
1968            for row_no in range(self._view.ui.list_pred_analysis_mono_overview.count()):
1969                tmp_raw_analysis_run_names.append(self._view.ui.list_pred_analysis_mono_overview.item(row_no).text())
1970
1971            self._active_task = tasks.Task(
1972                target=main_presenter_async.run_distance_analysis,
1973                args=(
1974                    tmp_raw_analysis_run_names,
1975                    self._current_project,
1976                    self._application_settings,
1977                    self._view.ui.cb_pred_analysis_mono_images.isChecked(),
1978                ),
1979                post_func=self.post_analysis_process,
1980            )
1981            self._active_task.start()
1982
1983            if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1984                os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1985            self.block_box_analysis.exec_()
1986            self.display_view_page()
1987
1988        elif tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1989            self.block_box_prediction.destroy(True)
1990            basic_boxes.ok(
1991                "Prediction",
1992                "Prediction failed because there was an error writing the fasta file(s)!",
1993                QtWidgets.QMessageBox.Critical,
1994            )
1995            self.display_view_page()
1996            self._project_watcher.show_valid_options(self._view.ui)
1997            constants.PYSSA_LOGGER.error(
1998                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1999            )
2000            self._view.wait_spinner.stop()
2001        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
2002            self.block_box_prediction.destroy(True)
2003            basic_boxes.ok(
2004                "Prediction",
2005                "Prediction failed because the fasta file(s) could not be found!",
2006                QtWidgets.QMessageBox.Critical,
2007            )
2008            self.display_view_page()
2009            self._project_watcher.show_valid_options(self._view.ui)
2010            constants.PYSSA_LOGGER.error(
2011                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2012            )
2013            self._view.wait_spinner.stop()
2014        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
2015            self.block_box_prediction.destroy(True)
2016            basic_boxes.ok(
2017                "Prediction",
2018                "Prediction failed because a subprocess failed!",
2019                QtWidgets.QMessageBox.Critical,
2020            )
2021            self.display_view_page()
2022            self._project_watcher.show_valid_options(self._view.ui)
2023            constants.PYSSA_LOGGER.error(
2024                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2025            )
2026            self._view.wait_spinner.stop()
2027        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2028            self.block_box_prediction.destroy(True)
2029            basic_boxes.ok(
2030                "Prediction",
2031                "Prediction failed because of an unknown error!",
2032                QtWidgets.QMessageBox.Critical,
2033            )
2034            self.display_view_page()
2035            self._project_watcher.show_valid_options(self._view.ui)
2036            constants.PYSSA_LOGGER.error(
2037                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2038            )
2039            self._view.wait_spinner.stop()
2040
2041    def mono_pred_analysis_structure_analysis_next_2(self) -> None:
2042        """Shows the gui elements for the chain selection of protein 1."""
2043        self._view.wait_spinner.start()
2044        tmp_proteins_to_predict: list[str] = []
2045        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
2046            tmp_proteins_to_predict.append(
2047                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text(),
2048            )
2049        self._active_task = tasks.Task(
2050            target=main_presenter_async.check_chains_for_subsequent_analysis,
2051            args=(
2052                self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2053                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
2054                self._current_project,
2055                tmp_proteins_to_predict,
2056            ),
2057            post_func=self.__await_mono_pred_analysis_structure_analysis_next_2,
2058        )
2059        self._active_task.start()
2060
2061    def __await_mono_pred_analysis_structure_analysis_next_2(self, result: tuple) -> None:
2062        _, tmp_analysis_name = result
2063        if tmp_analysis_name != "":
2064            gui_elements_to_show = [
2065                self._view.ui.btn_pred_analysis_mono_remove,
2066                self._view.ui.btn_pred_analysis_mono_add,
2067                self._view.ui.lbl_pred_analysis_mono_overview,
2068                self._view.ui.list_pred_analysis_mono_overview,
2069                self._view.ui.lbl_pred_analysis_mono_images,
2070                self._view.ui.cb_pred_analysis_mono_images,
2071                self._view.ui.btn_pred_analysis_mono_start,
2072                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
2073            ]
2074            gui_elements_to_hide = [
2075                self._view.ui.box_pred_analysis_mono_prot_struct_1,
2076                self._view.ui.box_pred_analysis_mono_prot_struct_2,
2077                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
2078                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
2079                self._view.ui.lbl_analysis_batch_vs_2,
2080                self._view.ui.lbl_pred_analysis_mono_ref_chains,
2081                self._view.ui.list_pred_analysis_mono_ref_chains,
2082                self._view.ui.lbl_pred_analysis_mono_model_chains,
2083                self._view.ui.list_pred_analysis_mono_model_chains,
2084                self._view.ui.btn_pred_analysis_mono_back_3,
2085                self._view.ui.btn_pred_analysis_mono_next_2,
2086                self._view.ui.btn_pred_analysis_mono_back_4,
2087                self._view.ui.btn_pred_analysis_mono_next_3,
2088                self._view.ui.btn_pred_analysis_mono_back_5,
2089                self._view.ui.btn_pred_analysis_mono_next_4,
2090            ]
2091            gui_utils.show_gui_elements(gui_elements_to_show)
2092            gui_utils.hide_gui_elements(gui_elements_to_hide)
2093            item = QtWidgets.QListWidgetItem(tmp_analysis_name)
2094            self._view.ui.list_pred_analysis_mono_overview.addItem(item)
2095            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
2096        else:
2097            gui_elements_to_show = [
2098                self._view.ui.lbl_pred_analysis_mono_overview,
2099                self._view.ui.list_pred_analysis_mono_overview,
2100                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
2101                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
2102                self._view.ui.lbl_analysis_batch_vs_2,
2103                self._view.ui.lbl_pred_analysis_mono_ref_chains,
2104                self._view.ui.list_pred_analysis_mono_ref_chains,
2105                self._view.ui.btn_pred_analysis_mono_back_4,
2106                self._view.ui.btn_pred_analysis_mono_next_3,
2107            ]
2108            gui_elements_to_hide = [
2109                self._view.ui.btn_pred_analysis_mono_remove,
2110                self._view.ui.btn_pred_analysis_mono_add,
2111                self._view.ui.box_pred_analysis_mono_prot_struct_1,
2112                self._view.ui.box_pred_analysis_mono_prot_struct_2,
2113                self._view.ui.btn_pred_analysis_mono_back_3,
2114                self._view.ui.btn_pred_analysis_mono_next_2,
2115                self._view.ui.lbl_pred_analysis_mono_model_chains,
2116                self._view.ui.list_pred_analysis_mono_model_chains,
2117                self._view.ui.btn_pred_analysis_mono_back_5,
2118                self._view.ui.btn_pred_analysis_mono_next_4,
2119                self._view.ui.lbl_pred_analysis_mono_images,
2120                self._view.ui.cb_pred_analysis_mono_images,
2121                self._view.ui.btn_pred_analysis_mono_start,
2122                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
2123            ]
2124            gui_utils.show_gui_elements(gui_elements_to_show)
2125            gui_utils.hide_gui_elements(gui_elements_to_hide)
2126            self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText(
2127                self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2128            )
2129            self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText(
2130                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
2131            )
2132            self._view.ui.list_pred_analysis_mono_ref_chains.clear()
2133            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(False)
2134            self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(True)
2135
2136            for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
2137                if (
2138                    self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text()
2139                    == self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText()
2140                ):
2141                    self._view.ui.list_pred_analysis_mono_ref_chains.addItem(
2142                        self._view.ui.table_pred_analysis_mono_prot_to_predict.item(i, 0).text(),
2143                    )
2144            if self._view.ui.list_pred_analysis_mono_ref_chains.count() == 0:
2145                tmp_protein = self._current_project.search_protein(
2146                    self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2147                )
2148                for tmp_chain in tmp_protein.chains:
2149                    if tmp_chain.chain_type == "protein_chain":
2150                        self._view.ui.list_pred_analysis_mono_ref_chains.addItem(tmp_chain.chain_letter)
2151            if self._view.ui.list_pred_analysis_mono_ref_chains.count() == 1:
2152                self._view.ui.lbl_pred_analysis_mono_ref_chains.setText(
2153                    f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()}.",
2154                )
2155            else:
2156                self._view.ui.lbl_pred_analysis_mono_ref_chains.setText(
2157                    f"Select chains in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()}.",
2158                )
2159        self._view.wait_spinner.stop()
2160
2161    # </editor-fold>
2162
2163    # <editor-fold desc="Multimer Prediction + Analysis functions">
2164    def start_multimer_prediction_analysis(self) -> None:
2165        """Sets up the prediction process."""
2166        self._view.wait_spinner.start()
2167        self.prediction_type = constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS
2168        constants.PYSSA_LOGGER.info("Begin prediction process.")
2169        self.update_status("Begin prediction process ...")
2170        predictions: list[
2171            prediction_protein_info.PredictionProteinInfo
2172        ] = prediction_util.get_prediction_name_and_seq_from_table(
2173            self._view.ui.table_pred_analysis_multi_prot_to_predict,
2174        )
2175
2176        self._active_task = tasks.Task(
2177            target=main_presenter_async.predict_protein_with_colabfold,
2178            args=(
2179                predictions,
2180                self.prediction_configuration,
2181                self._current_project,
2182            ),
2183            post_func=self.__await_multimer_prediction_for_subsequent_analysis,
2184        )
2185        self._active_task.start()
2186
2187        self.block_box_prediction = QtWidgets.QMessageBox()
2188        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
2189        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
2190        styles.set_stylesheet(self.block_box_prediction)
2191        self.block_box_prediction.setWindowTitle("Structure Prediction")
2192        self.block_box_prediction.setText("A prediction is currently running.")
2193        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
2194        self.block_box_prediction.exec_()
2195        if self.block_box_prediction.clickedButton() == btn_abort:
2196            self.abort_prediction()
2197            self.block_box_prediction.close()
2198            self._view.wait_spinner.stop()
2199        else:
2200            self.block_box_prediction.close()
2201            self._view.wait_spinner.stop()
2202
2203    def __await_multimer_prediction_for_subsequent_analysis(self, result: tuple) -> None:
2204        tmp_exit_code = result[0]
2205        tmp_exit_code_description = [1]
2206        if tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
2207            # Prediction was successful
2208            self.block_box_prediction.destroy(True)
2209            constants.PYSSA_LOGGER.info("All structure predictions are done.")
2210            self.update_status("All structure predictions are done.")
2211            constants.PYSSA_LOGGER.info("Begin analysis process.")
2212            self.update_status("Begin analysis process ...")
2213            tmp_raw_analysis_run_names: list = []
2214            for row_no in range(self._view.ui.list_pred_analysis_multi_overview.count()):
2215                tmp_raw_analysis_run_names.append(self._view.ui.list_pred_analysis_multi_overview.item(row_no).text())
2216
2217            self._active_task = tasks.Task(
2218                target=main_presenter_async.run_distance_analysis,
2219                args=(
2220                    tmp_raw_analysis_run_names,
2221                    self._current_project,
2222                    self._application_settings,
2223                    self._view.ui.cb_pred_analysis_multi_images.isChecked(),
2224                ),
2225                post_func=self.post_analysis_process,
2226            )
2227            self._active_task.start()
2228
2229            if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2230                os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2231            self.block_box_analysis.exec_()
2232            self.display_view_page()
2233
2234        elif tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
2235            self.block_box_prediction.destroy(True)
2236            basic_boxes.ok(
2237                "Prediction",
2238                "Prediction failed because there was an error writing the fasta file(s)!",
2239                QtWidgets.QMessageBox.Critical,
2240            )
2241            self.display_view_page()
2242            self._project_watcher.show_valid_options(self._view.ui)
2243            constants.PYSSA_LOGGER.error(
2244                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2245            )
2246            self._view.wait_spinner.stop()
2247        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
2248            self.block_box_prediction.destroy(True)
2249            basic_boxes.ok(
2250                "Prediction",
2251                "Prediction failed because the fasta file(s) could not be found!",
2252                QtWidgets.QMessageBox.Critical,
2253            )
2254            self.display_view_page()
2255            self._project_watcher.show_valid_options(self._view.ui)
2256            constants.PYSSA_LOGGER.error(
2257                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2258            )
2259            self._view.wait_spinner.stop()
2260        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
2261            self.block_box_prediction.destroy(True)
2262            basic_boxes.ok(
2263                "Prediction",
2264                "Prediction failed because a subprocess failed!",
2265                QtWidgets.QMessageBox.Critical,
2266            )
2267            self.display_view_page()
2268            self._project_watcher.show_valid_options(self._view.ui)
2269            constants.PYSSA_LOGGER.error(
2270                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2271            )
2272            self._view.wait_spinner.stop()
2273        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2274            self.block_box_prediction.destroy(True)
2275            basic_boxes.ok(
2276                "Prediction",
2277                "Prediction failed because of an unknown error!",
2278                QtWidgets.QMessageBox.Critical,
2279            )
2280            self.display_view_page()
2281            self._project_watcher.show_valid_options(self._view.ui)
2282            constants.PYSSA_LOGGER.error(
2283                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2284            )
2285            self._view.wait_spinner.stop()
2286
2287    def multi_pred_analysis_structure_analysis_next_2(self) -> None:
2288        """Shows the gui elements to select the chains in protein 1."""
2289        self._view.wait_spinner.start()
2290        tmp_proteins_to_predict: list[str] = []
2291        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
2292            tmp_proteins_to_predict.append(
2293                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text(),
2294            )
2295        self._active_task = tasks.Task(
2296            target=main_presenter_async.check_chains_for_subsequent_analysis,
2297            args=(
2298                self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2299                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
2300                self._current_project,
2301                tmp_proteins_to_predict,
2302            ),
2303            post_func=self.__await_multi_pred_analysis_structure_analysis_next_2,
2304        )
2305        self._active_task.start()
2306
2307    def __await_multi_pred_analysis_structure_analysis_next_2(self, result: tuple) -> None:
2308        # fixme: something is not quite right with the detection of the chains!
2309        _, tmp_analysis_name = result
2310        if tmp_analysis_name != "":
2311            gui_elements_to_show = [
2312                self._view.ui.btn_pred_analysis_multi_remove,
2313                self._view.ui.btn_pred_analysis_multi_add,
2314                self._view.ui.lbl_pred_analysis_multi_overview,
2315                self._view.ui.list_pred_analysis_multi_overview,
2316                self._view.ui.lbl_pred_analysis_multi_images,
2317                self._view.ui.cb_pred_analysis_multi_images,
2318                self._view.ui.btn_pred_analysis_multi_start,
2319                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
2320            ]
2321            gui_elements_to_hide = [
2322                self._view.ui.box_pred_analysis_multi_prot_struct_1,
2323                self._view.ui.box_pred_analysis_multi_prot_struct_2,
2324                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
2325                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
2326                self._view.ui.lbl_analysis_batch_vs_3,
2327                self._view.ui.lbl_pred_analysis_multi_ref_chains,
2328                self._view.ui.list_pred_analysis_multi_ref_chains,
2329                self._view.ui.lbl_pred_analysis_multi_model_chains,
2330                self._view.ui.list_pred_analysis_multi_model_chains,
2331                self._view.ui.btn_pred_analysis_multi_back_3,
2332                self._view.ui.btn_pred_analysis_multi_next_2,
2333                self._view.ui.btn_pred_analysis_multi_back_4,
2334                self._view.ui.btn_pred_analysis_multi_next_3,
2335                self._view.ui.btn_pred_analysis_multi_back_5,
2336                self._view.ui.btn_pred_analysis_multi_next_4,
2337            ]
2338            gui_utils.show_gui_elements(gui_elements_to_show)
2339            gui_utils.hide_gui_elements(gui_elements_to_hide)
2340            item = QtWidgets.QListWidgetItem(tmp_analysis_name)
2341            self._view.ui.list_pred_analysis_multi_overview.addItem(item)
2342            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
2343        else:
2344            gui_elements_to_show = [
2345                self._view.ui.lbl_pred_analysis_multi_overview,
2346                self._view.ui.list_pred_analysis_multi_overview,
2347                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
2348                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
2349                self._view.ui.lbl_analysis_batch_vs_3,
2350                self._view.ui.lbl_pred_analysis_multi_ref_chains,
2351                self._view.ui.list_pred_analysis_multi_ref_chains,
2352                self._view.ui.btn_pred_analysis_multi_back_4,
2353                self._view.ui.btn_pred_analysis_multi_next_3,
2354            ]
2355            gui_elements_to_hide = [
2356                self._view.ui.btn_pred_analysis_multi_remove,
2357                self._view.ui.btn_pred_analysis_multi_add,
2358                self._view.ui.box_pred_analysis_multi_prot_struct_1,
2359                self._view.ui.box_pred_analysis_multi_prot_struct_2,
2360                self._view.ui.btn_pred_analysis_multi_back_3,
2361                self._view.ui.btn_pred_analysis_multi_next_2,
2362                self._view.ui.lbl_pred_analysis_multi_model_chains,
2363                self._view.ui.list_pred_analysis_multi_model_chains,
2364                self._view.ui.btn_pred_analysis_multi_back_5,
2365                self._view.ui.btn_pred_analysis_multi_next_4,
2366                self._view.ui.lbl_pred_analysis_multi_images,
2367                self._view.ui.cb_pred_analysis_multi_images,
2368                self._view.ui.btn_pred_analysis_multi_start,
2369                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
2370            ]
2371            gui_utils.show_gui_elements(gui_elements_to_show)
2372            gui_utils.hide_gui_elements(gui_elements_to_hide)
2373            self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText(
2374                self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2375            )
2376            self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText(
2377                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
2378            )
2379            self._view.ui.list_pred_analysis_multi_ref_chains.clear()
2380            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(False)
2381            self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(True)
2382
2383            for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
2384                if (
2385                    self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text()
2386                    == self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText()
2387                ):
2388                    self._view.ui.list_pred_analysis_multi_ref_chains.addItem(
2389                        self._view.ui.table_pred_analysis_multi_prot_to_predict.item(i, 0).text(),
2390                    )
2391            if self._view.ui.list_pred_analysis_multi_ref_chains.count() == 0:
2392                tmp_protein = self._current_project.search_protein(
2393                    self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2394                )
2395                for tmp_chain in tmp_protein.chains:
2396                    if tmp_chain.chain_type == "protein_chain":
2397                        self._view.ui.list_pred_analysis_multi_ref_chains.addItem(tmp_chain.chain_letter)
2398            if self._view.ui.list_pred_analysis_multi_ref_chains.count() == 1:
2399                self._view.ui.lbl_pred_analysis_multi_ref_chains.setText(
2400                    f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()}.",
2401                )
2402            else:
2403                self._view.ui.lbl_pred_analysis_multi_ref_chains.setText(
2404                    f"Select chains in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()}.",
2405                )
2406        self._view.wait_spinner.stop()
2407
2408    # </editor-fold>
2409
2410    # <editor-fold desc="Structure Analysis functions">
2411    def post_analysis_process(self, an_exit_code: tuple[int, str]) -> None:
2412        """Post process after the analysis thread finished."""
2413        constants.PYSSA_LOGGER.debug("post_analysis_process() started ...")
2414        if an_exit_code[0] == exit_codes.ERROR_DISTANCE_ANALYSIS_FAILED[0]:
2415            self.block_box_analysis.destroy(True)
2416            basic_boxes.ok(
2417                "Distance analysis",
2418                "Distance analysis failed because there was an error during the analysis!",
2419                QtWidgets.QMessageBox.Critical,
2420            )
2421            constants.PYSSA_LOGGER.error(
2422                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2423            )
2424        elif an_exit_code[0] == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2425            self.block_box_analysis.destroy(True)
2426            basic_boxes.ok(
2427                "Distance analysis",
2428                "Distance analysis failed because of an unknown error!",
2429                QtWidgets.QMessageBox.Critical,
2430            )
2431            constants.PYSSA_LOGGER.error(
2432                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2433            )
2434        elif an_exit_code[0] == exit_codes.EXIT_CODE_ZERO[0]:
2435            self._current_project.serialize_project(self._current_project.get_project_xml_path())
2436            constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2437            self.block_box_analysis.destroy(True)
2438            basic_boxes.ok(
2439                "Structure analysis",
2440                "All structure analysis' are done. Go to results to check the new results.",
2441                QtWidgets.QMessageBox.Information,
2442            )
2443            constants.PYSSA_LOGGER.info("All structure analysis' are done.")
2444
2445        self._project_watcher.show_valid_options(self._view.ui)
2446        self.display_view_page()
2447        self._init_batch_analysis_page()
2448
2449    def start_process_batch(self) -> None:
2450        """Sets up the worker for the analysis task."""
2451        constants.PYSSA_LOGGER.info("Begin analysis process.")
2452
2453        tmp_raw_analysis_run_names: list = []
2454        for row_no in range(self._view.ui.list_analysis_batch_overview.count()):
2455            tmp_raw_analysis_run_names.append(self._view.ui.list_analysis_batch_overview.item(row_no).text())
2456        self._active_task = tasks.Task(
2457            target=main_presenter_async.run_distance_analysis,
2458            args=(
2459                tmp_raw_analysis_run_names,
2460                self._current_project,
2461                self._application_settings,
2462                self._view.ui.cb_analysis_images.isChecked(),
2463            ),
2464            post_func=self.post_analysis_process,
2465        )
2466        self._active_task.start()
2467
2468        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2469            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2470
2471        self.block_box_analysis.exec_()
2472        self.display_view_page()
2473
2474    def structure_analysis_next(self) -> None:
2475        """Shows the gui elements to select the chains in protein 1."""
2476        self._view.wait_spinner.start()
2477        self._active_task = tasks.Task(
2478            target=main_presenter_async.check_chains_for_analysis,
2479            args=(
2480                self._view.ui.box_analysis_batch_prot_struct_1.currentText(),
2481                self._view.ui.box_analysis_batch_prot_struct_2.currentText(),
2482                self._current_project,
2483            ),
2484            post_func=self.__await_structure_analysis_next,
2485        )
2486        self._active_task.start()
2487
2488    def __await_structure_analysis_next(self, result: tuple) -> None:
2489        _, tmp_is_only_one_chain, tmp_analysis_run_name, tmp_protein_1, tmp_protein_2 = result
2490
2491        if tmp_is_only_one_chain:
2492            gui_elements_to_show = [
2493                self._view.ui.btn_analysis_batch_remove,
2494                self._view.ui.btn_analysis_batch_add,
2495                self._view.ui.lbl_analysis_batch_overview,
2496                self._view.ui.list_analysis_batch_overview,
2497                self._view.ui.lbl_analysis_batch_images,
2498                self._view.ui.cb_analysis_batch_images,
2499                self._view.ui.btn_analysis_batch_start,
2500            ]
2501            gui_elements_to_hide = [
2502                self._view.ui.box_analysis_batch_prot_struct_1,
2503                self._view.ui.box_analysis_batch_prot_struct_2,
2504                self._view.ui.lbl_analysis_batch_prot_struct_1,
2505                self._view.ui.lbl_analysis_batch_prot_struct_2,
2506                self._view.ui.lbl_analysis_batch_vs,
2507                self._view.ui.lbl_analysis_batch_ref_chains,
2508                self._view.ui.list_analysis_batch_ref_chains,
2509                self._view.ui.lbl_analysis_batch_model_chains,
2510                self._view.ui.list_analysis_batch_model_chains,
2511                self._view.ui.btn_analysis_batch_back,
2512                self._view.ui.btn_analysis_batch_next,
2513                self._view.ui.btn_analysis_batch_back_2,
2514                self._view.ui.btn_analysis_batch_next_2,
2515                self._view.ui.btn_analysis_batch_back_3,
2516                self._view.ui.btn_analysis_batch_next_3,
2517            ]
2518            gui_utils.show_gui_elements(gui_elements_to_show)
2519            gui_utils.hide_gui_elements(gui_elements_to_hide)
2520            item = QtWidgets.QListWidgetItem(tmp_analysis_run_name)
2521            self._view.ui.list_analysis_batch_overview.addItem(item)
2522            self._view.ui.btn_analysis_batch_remove.setEnabled(False)
2523        else:
2524            gui_elements_to_show = [
2525                self._view.ui.lbl_analysis_batch_overview,
2526                self._view.ui.list_analysis_batch_overview,
2527                self._view.ui.lbl_analysis_batch_prot_struct_1,
2528                self._view.ui.lbl_analysis_batch_prot_struct_2,
2529                self._view.ui.lbl_analysis_batch_vs,
2530                self._view.ui.lbl_analysis_batch_ref_chains,
2531                self._view.ui.list_analysis_batch_ref_chains,
2532                self._view.ui.btn_analysis_batch_back_2,
2533                self._view.ui.btn_analysis_batch_next_2,
2534            ]
2535            gui_elements_to_hide = [
2536                self._view.ui.btn_analysis_batch_remove,
2537                self._view.ui.btn_analysis_batch_add,
2538                self._view.ui.box_analysis_batch_prot_struct_1,
2539                self._view.ui.box_analysis_batch_prot_struct_2,
2540                self._view.ui.btn_analysis_batch_back,
2541                self._view.ui.btn_analysis_batch_next,
2542                self._view.ui.lbl_analysis_batch_model_chains,
2543                self._view.ui.list_analysis_batch_model_chains,
2544                self._view.ui.btn_analysis_batch_back_3,
2545                self._view.ui.btn_analysis_batch_next_3,
2546                self._view.ui.lbl_analysis_batch_images,
2547                self._view.ui.cb_analysis_batch_images,
2548                self._view.ui.btn_analysis_batch_start,
2549            ]
2550            gui_utils.show_gui_elements(gui_elements_to_show)
2551            gui_utils.hide_gui_elements(gui_elements_to_hide)
2552            self._view.ui.lbl_analysis_batch_prot_struct_1.setText(
2553                self._view.ui.box_analysis_batch_prot_struct_1.currentText(),
2554            )
2555            self._view.ui.lbl_analysis_batch_prot_struct_2.setText(
2556                self._view.ui.box_analysis_batch_prot_struct_2.currentText(),
2557            )
2558            self._view.ui.list_analysis_batch_ref_chains.clear()
2559            self._view.ui.btn_analysis_batch_next_2.setEnabled(False)
2560            self._view.ui.list_analysis_batch_ref_chains.setEnabled(True)
2561
2562            for tmp_chain in tmp_protein_1.chains:
2563                if tmp_chain.chain_type == "protein_chain":
2564                    self._view.ui.list_analysis_batch_ref_chains.addItem(tmp_chain.chain_letter)
2565
2566            if self._view.ui.list_analysis_batch_ref_chains.count() == 1:
2567                self._view.ui.lbl_analysis_batch_ref_chains.setText(
2568                    f"Select chain in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_1.text()}.",
2569                )
2570            else:
2571                self._view.ui.lbl_analysis_batch_ref_chains.setText(
2572                    f"Select chains in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_1.text()}.",
2573                )
2574        self._view.wait_spinner.stop()
2575
2576    # </editor-fold>
2577
2578    # <editor-fold desc="Analysis Images">
2579    def post_image_creation_process(self) -> None:
2580        """Post method after the image creation task is finished."""
2581        self._current_project.serialize_project(self._current_project.get_project_xml_path())
2582        constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2583        self.block_box_images.destroy(True)
2584        basic_boxes.ok(
2585            "Analysis Images",
2586            "All images of all analysis' have been created. Go to results to check the new results.",
2587            QtWidgets.QMessageBox.Information,
2588        )
2589        constants.PYSSA_LOGGER.info("All images of all analysis' have been created.")
2590        self._init_analysis_image_page()
2591        self.display_view_page()
2592        self._project_watcher.show_valid_options(self._view.ui)
2593
2594    def start_automatic_image_creation(self) -> None:
2595        """Sets up the worker for the image creation process."""
2596        constants.PYSSA_LOGGER.info("Begin image creation process.")
2597        # self.worker_image_creation = workers.BatchImageWorkerPool(
2598        #    self._view.ui.list_analysis_images_struct_analysis, self._view.ui.list_analysis_images_creation_struct_analysis,
2599        #    self._view.status_bar, self._current_project)
2600        constants.PYSSA_LOGGER.info("Thread started for image creation process.")
2601        # self.threadpool.start(self.worker_image_creation)
2602
2603        # <editor-fold desc="Worker setup">
2604        # TODO: test code below
2605        # --Begin: worker setup
2606        self.tmp_thread = QtCore.QThread()
2607        self.tmp_worker = task_workers.BatchImageWorker(
2608            self._view.ui.list_analysis_images_struct_analysis,
2609            self._view.ui.list_analysis_images_creation_struct_analysis,
2610            self._view.status_bar,
2611            self._current_project,
2612        )
2613        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.display_view_page)
2614        self.tmp_worker.finished.connect(self.post_image_creation_process)
2615        self.tmp_thread.start()
2616        # --End: worker setup
2617
2618        # </editor-fold>
2619
2620        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2621            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2622
2623        self._view.ui.list_analysis_images_struct_analysis.setEnabled(False)
2624        self._view.ui.list_analysis_images_creation_struct_analysis.setEnabled(False)
2625
2626        # gui_elements_to_show = [
2627        #     self._view.ui.btn_analysis_abort,
2628        # ]
2629        # gui_elements_to_hide = [
2630        #     self._view.ui.btn_save_project,
2631        #     self._view.ui.btn_edit_page,
2632        #     self._view.ui.btn_view_page,
2633        #     self._view.ui.btn_use_page,
2634        #     self._view.ui.btn_export_project,
2635        #     self._view.ui.btn_close_project,
2636        #     self._view.ui.btn_batch_analysis_page,
2637        #     self._view.ui.btn_image_analysis_page,
2638        #     self._view.ui.btn_results_page,
2639        #     self._view.ui.lbl_handle_pymol_session,
2640        #     self._view.ui.btn_image_page,
2641        #     self._view.ui.btn_hotspots_page,
2642        # ]
2643        # gui_utils.manage_gui_visibility(gui_elements_to_show, gui_elements_to_hide)
2644
2645        self.block_box_images.exec_()
2646
2647    # </editor-fold>
2648
2649    # <editor-fold desc="Results page functions">
2650    def show_analysis_results_options(self) -> None:
2651        """Shows the combo box of protein pairs."""
2652        self.results_management.show_stage_x(0)
2653
2654    def show_results_interactions(self, gui_elements_to_show: list = None, gui_elements_to_hide: list = None) -> None:
2655        """Shows the gui elements of the results page.
2656
2657        Args:
2658            gui_elements_to_show: a list of gui elements which should get displayed.
2659            gui_elements_to_hide: a list of gui elements which should get hidden.
2660        """
2661        if gui_elements_to_hide is not None:
2662            self.results_management.show_gui_elements_stage_x(
2663                [0, 1],
2664                [],
2665                show_specific_elements=[
2666                    self._view.ui.lbl_results_analysis_options,
2667                    self._view.ui.cb_results_analysis_options,
2668                ],
2669                hide_specific_elements=gui_elements_to_hide,
2670            )
2671        else:
2672            self.results_management.show_gui_elements_stage_x(
2673                [0, 1],
2674                [],
2675                show_specific_elements=[
2676                    self._view.ui.lbl_results_analysis_options,
2677                    self._view.ui.cb_results_analysis_options,
2678                ],
2679            )
2680
2681    def load_results(self) -> None:
2682        """Sets up the worker for the result loading process."""
2683        self._view.wait_spinner.start()
2684        if self.is_distance_plot_open:
2685            self.distance_plot_dialog.close()
2686            self.is_distance_plot_open = False
2687        self.results_name = self._view.ui.cb_results_analysis_options.currentText()
2688        if self.results_name == "":
2689            self.show_analysis_results_options()
2690            self._view.wait_spinner.stop()
2691            return
2692        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
2693
2694        self._active_task = tasks.Task(
2695            target=main_presenter_async.load_results,
2696            args=(
2697                self._current_project,
2698                self.results_name,
2699            ),
2700            post_func=self.__await_load_results,
2701        )
2702        self._active_task.start()
2703
2704        self._view.ui.list_results_interest_regions.clear()
2705        self._view.status_bar.showMessage(f"Loading results of {self.results_name} ...")
2706
2707    def __await_load_results(self, result: tuple) -> None:
2708        _, images_type, self.current_session, tmp_rmsd, tmp_no_aligned_residues = result
2709
2710        if images_type == constants.IMAGES_ALL:
2711            gui_elements_to_show = [
2712                self._view.ui.lbl_results_analysis_options,
2713                self._view.ui.cb_results_analysis_options,
2714                self._view.ui.lbl_results_rmsd,
2715                self._view.ui.txt_results_rmsd,
2716                self._view.ui.lbl_color_rmsd,
2717                self._view.ui.btn_color_rmsd,
2718                self._view.ui.lbl_results_aligned_residues,
2719                self._view.ui.txt_results_aligned_residues,
2720                self._view.ui.lbl_results_distance_plot,
2721                self._view.ui.btn_view_distance_plot,
2722                self._view.ui.lbl_results_distance_histogram,
2723                self._view.ui.btn_view_distance_histogram,
2724                self._view.ui.lbl_results_distance_table,
2725                self._view.ui.btn_view_distance_table,
2726                self._view.ui.lbl_results_structure_alignment,
2727                self._view.ui.btn_view_struct_alignment,
2728                self._view.ui.lbl_results_interest_regions,
2729                self._view.ui.list_results_interest_regions,
2730                self._view.ui.btn_view_interesting_region,
2731            ]
2732            gui_utils.show_gui_elements(gui_elements_to_show)
2733            for tmp_filename in os.listdir(constants.CACHE_STRUCTURE_ALN_IMAGES_INTERESTING_REGIONS_DIR):
2734                self._view.ui.list_results_interest_regions.addItem(tmp_filename)
2735            self._view.ui.list_results_interest_regions.sortItems()
2736        elif images_type == constants.IMAGES_STRUCT_ALN_ONLY:
2737            gui_elements_to_show = [
2738                self._view.ui.lbl_results_analysis_options,
2739                self._view.ui.cb_results_analysis_options,
2740                self._view.ui.lbl_results_rmsd,
2741                self._view.ui.txt_results_rmsd,
2742                self._view.ui.lbl_color_rmsd,
2743                self._view.ui.btn_color_rmsd,
2744                self._view.ui.lbl_results_aligned_residues,
2745                self._view.ui.txt_results_aligned_residues,
2746                self._view.ui.lbl_results_distance_plot,
2747                self._view.ui.btn_view_distance_plot,
2748                self._view.ui.lbl_results_distance_histogram,
2749                self._view.ui.btn_view_distance_histogram,
2750                self._view.ui.lbl_results_distance_table,
2751                self._view.ui.btn_view_distance_table,
2752                self._view.ui.lbl_results_structure_alignment,
2753                self._view.ui.btn_view_struct_alignment,
2754            ]
2755            gui_elements_to_hide = [
2756                self._view.ui.lbl_results_interest_regions,
2757                self._view.ui.list_results_interest_regions,
2758                self._view.ui.btn_view_interesting_region,
2759            ]
2760            gui_utils.show_gui_elements(gui_elements_to_show)
2761            gui_utils.hide_gui_elements(gui_elements_to_hide)
2762            self._view.ui.list_results_interest_regions.sortItems()
2763        elif images_type == constants.IMAGES_NONE:
2764            gui_elements_to_show = [
2765                self._view.ui.lbl_results_analysis_options,
2766                self._view.ui.cb_results_analysis_options,
2767                self._view.ui.lbl_results_rmsd,
2768                self._view.ui.txt_results_rmsd,
2769                self._view.ui.lbl_color_rmsd,
2770                self._view.ui.btn_color_rmsd,
2771                self._view.ui.lbl_results_aligned_residues,
2772                self._view.ui.txt_results_aligned_residues,
2773                self._view.ui.lbl_results_distance_plot,
2774                self._view.ui.btn_view_distance_plot,
2775                self._view.ui.lbl_results_distance_histogram,
2776                self._view.ui.btn_view_distance_histogram,
2777                self._view.ui.lbl_results_distance_table,
2778                self._view.ui.btn_view_distance_table,
2779            ]
2780            gui_elements_to_hide = [
2781                self._view.ui.lbl_results_structure_alignment,
2782                self._view.ui.btn_view_struct_alignment,
2783                self._view.ui.lbl_results_interest_regions,
2784                self._view.ui.list_results_interest_regions,
2785                self._view.ui.btn_view_interesting_region,
2786            ]
2787            gui_utils.show_gui_elements(gui_elements_to_show)
2788            gui_utils.hide_gui_elements(gui_elements_to_hide)
2789        else:
2790            raise ValueError("Illegal argument.")
2791
2792        self._view.ui.txt_results_rmsd.setText(str(tmp_rmsd))
2793        self._view.ui.txt_results_aligned_residues.setText(str(tmp_no_aligned_residues))
2794        self._view.status_bar.showMessage(f"Current workspace: {str(self._workspace_path)}")
2795        self.main_window_state.results_page.results_name = self._view.ui.cb_results_analysis_options.currentText()
2796        self._view.wait_spinner.stop()
2797
2798    def color_protein_pair_by_rmsd(self) -> None:
2799        """Colors the residues in 5 colors depending on their distance to the reference."""
2800        self._view.wait_spinner.start()
2801        self._active_task = tasks.Task(
2802            target=main_presenter_async.color_protein_pair_by_rmsd_value,
2803            args=(
2804                self._current_project,
2805                self.results_name,
2806            ),
2807            post_func=self.__await_color_protein_pair_by_rmsd,
2808        )
2809        self._active_task.start()
2810        self._view.status_bar.showMessage("Coloring protein pair by RMSD value ...")
2811        # hide unnecessary representations
2812        # fixme: it might be a problem to hide any representation at this point
2813        # cmd.hide("cartoon", tmp_protein_pair.protein_1.get_molecule_object())
2814        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")
2815        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")
2816
2817    def __await_color_protein_pair_by_rmsd(self, result: tuple) -> None:
2818        self._view.wait_spinner.stop()
2819
2820    # </editor-fold>
2821
2822    # <editor-fold desc="Display page functions">
2823    def display_structure_alignment(self) -> None:
2824        """Opens a window which displays the image of the structure alignment."""
2825        png_dialog = QtWidgets.QDialog(self._view)
2826        label = QtWidgets.QLabel(self._view)
2827        pathlib.Path(
2828            f"{self._workspace_path}/{self._view.ui.lbl_current_project_name.text()}/results/{self.results_name}",
2829        )
2830        self._view.ui.cb_results_analysis_options.currentText()
2831        pixmap = QtGui.QPixmap(
2832            f"{constants.CACHE_STRUCTURE_ALN_IMAGES_DIR}/structure_aln_{self._view.ui.cb_results_analysis_options.currentText()}",
2833        )
2834        # TO-DO: Create setting for min. image size
2835        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2836        label.setPixmap(pixmap)
2837        label.setScaledContents(True)
2838        png_dialog_layout = QtWidgets.QHBoxLayout()
2839        png_dialog_layout.addWidget(label)
2840        png_dialog.setLayout(png_dialog_layout)
2841        png_dialog.setWindowTitle("Image of: structure alignment")
2842        png_dialog.show()
2843
2844    def display_distance_plot(self) -> None:
2845        """Opens a window which displays the distance plot."""
2846        protein_pair_of_analysis = self._current_project.search_protein_pair(
2847            self._view.ui.cb_results_analysis_options.currentText(),
2848        )
2849
2850        tmp_dialog = plot_view.PlotView(protein_pair_of_analysis, self._current_project, self._view.ui.cb_results_analysis_options.currentText())
2851        tmp_dialog.exec_()
2852
2853        # self.distance_plot_dialog = dialog_distance_plot.DialogDistancePlot(protein_pair_of_analysis, self._current_project,
2854        #                                                                     self._view.ui.cb_results_analysis_options.currentText())
2855        # self.distance_plot_dialog.setWindowModality(Qt.WindowModal)
2856        # self.is_distance_plot_open = True
2857        # self.distance_plot_dialog.exec_()
2858
2859    def display_distance_histogram(self) -> None:
2860        """Opens a window which displays the distance histogram."""
2861        if self.is_distance_plot_open:
2862            self.distance_plot_dialog.close()
2863            self.is_distance_plot_open = False
2864        protein_pair_of_analysis = self._current_project.search_protein_pair(
2865            self._view.ui.cb_results_analysis_options.currentText(),
2866        )
2867        dialog = dialog_distance_histogram.DialogDistanceHistogram(protein_pair_of_analysis)
2868        dialog.exec_()
2869
2870    def display_interesting_region(self) -> None:
2871        """Displays an image of an interesting region."""
2872        if self.is_distance_plot_open:
2873            self.distance_plot_dialog.close()
2874            self.is_distance_plot_open = False
2875        png_dialog = QtWidgets.QDialog(self._view)
2876        label = QtWidgets.QLabel(self._view)
2877        file_name = self._view.ui.list_results_interest_regions.currentItem().text()
2878        pixmap = QtGui.QPixmap(f"{constants.CACHE_STRUCTURE_ALN_IMAGES_INTERESTING_REGIONS_DIR}/{file_name}")
2879        # TODO: Create setting for min. image size
2880        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2881        label.setPixmap(pixmap)
2882        label.setScaledContents(True)
2883        png_dialog_layout = QtWidgets.QHBoxLayout()
2884        png_dialog_layout.addWidget(label)
2885        png_dialog.setLayout(png_dialog_layout)
2886        png_dialog.setWindowTitle(f"Image of: {file_name}")
2887        png_dialog.show()
2888
2889    def display_distance_table(self) -> None:
2890        """Displays the distances in a table."""
2891        if self.is_distance_plot_open:
2892            self.distance_plot_dialog.close()
2893            self.is_distance_plot_open = False
2894        csv_model = QtGui.QStandardItemModel()
2895        csv_model.setColumnCount(7)
2896        labels = [
2897            "Residue pair no.",
2898            "Protein 1 Chain",
2899            "Protein 1 Position",
2900            "Protein 1 Residue",
2901            "Protein 2 Chain",
2902            "Protein 2 Position",
2903            "Protein 2 Residue",
2904            "Distance in Ã…",
2905        ]
2906        csv_model.setHorizontalHeaderLabels(labels)
2907        table_dialog = QtWidgets.QDialog(self._view)
2908        table_view = QtWidgets.QTableView()
2909        table_view.setModel(csv_model)
2910
2911        tmp_protein_pair = self._current_project.search_protein_pair(
2912            self._view.ui.cb_results_analysis_options.currentText(),
2913        )
2914        csv_filepath = pathlib.Path(f"{constants.CACHE_CSV_DIR}/{tmp_protein_pair.name}.csv")
2915        if not os.path.exists(constants.CACHE_CSV_DIR):
2916            os.mkdir(constants.CACHE_CSV_DIR)
2917        tmp_protein_pair = self._current_project.search_protein_pair(self.results_name)
2918
2919        distance_data = tmp_protein_pair.distance_analysis.analysis_results.distance_data
2920        distance_data_array = np.array(
2921            [
2922                distance_data[pyssa_keys.ARRAY_DISTANCE_INDEX],
2923                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_CHAIN],
2924                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_POSITION],
2925                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_RESI],
2926                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_CHAIN],
2927                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_POSITION],
2928                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_RESI],
2929                distance_data[pyssa_keys.ARRAY_DISTANCE_DISTANCES],
2930            ],
2931        )
2932        distance_data_array_transpose = distance_data_array.transpose()
2933        with open(csv_filepath, mode="w", newline="") as file:
2934            writer = csv.writer(file, delimiter=",")
2935            writer.writerows(distance_data_array_transpose)
2936
2937        file.close()
2938
2939        with open(csv_filepath, "r", encoding="utf-8") as csv_file:
2940            i = 0
2941            for line in csv_file:
2942                tmp_list = line.split(",")
2943                # tmp_list.pop(0)
2944                standard_item_list = []
2945                pair_no_item = QtGui.QStandardItem()
2946                pair_no_item.setData(int(tmp_list[0]), role=QtCore.Qt.DisplayRole)
2947                ref_chain_item = QtGui.QStandardItem()
2948                ref_chain_item.setData(str(tmp_list[1]), role=QtCore.Qt.DisplayRole)
2949                ref_pos_item = QtGui.QStandardItem()
2950                ref_pos_item.setData(int(tmp_list[2]), role=QtCore.Qt.DisplayRole)
2951                ref_resi_item = QtGui.QStandardItem()
2952                ref_resi_item.setData(str(tmp_list[3]), role=QtCore.Qt.DisplayRole)
2953                model_chain_item = QtGui.QStandardItem()
2954                model_chain_item.setData(str(tmp_list[4]), role=QtCore.Qt.DisplayRole)
2955                model_pos_item = QtGui.QStandardItem()
2956                model_pos_item.setData(int(tmp_list[5]), role=QtCore.Qt.DisplayRole)
2957                model_resi_item = QtGui.QStandardItem()
2958                model_resi_item.setData(str(tmp_list[6]), role=QtCore.Qt.DisplayRole)
2959                distance_item = QtGui.QStandardItem()
2960                distance_item.setData(float(tmp_list[7]), role=QtCore.Qt.DisplayRole)
2961                standard_item_list.append(pair_no_item)
2962                standard_item_list.append(ref_chain_item)
2963                standard_item_list.append(ref_pos_item)
2964                standard_item_list.append(ref_resi_item)
2965                standard_item_list.append(model_chain_item)
2966                standard_item_list.append(model_pos_item)
2967                standard_item_list.append(model_resi_item)
2968                standard_item_list.append(distance_item)
2969                csv_model.insertRow(i, standard_item_list)
2970            i += 1
2971        csv_file.close()
2972        csv_model.removeRow(0)
2973        table_view.setAlternatingRowColors(True)
2974        table_view.resizeColumnsToContents()
2975        table_view.verticalHeader().setVisible(False)
2976        table_view.setSortingEnabled(True)
2977        table_view.sortByColumn(0, QtCore.Qt.AscendingOrder)
2978        table_dialog_layout = QtWidgets.QHBoxLayout()
2979        table_dialog_layout.addWidget(table_view)
2980        table_dialog.setLayout(table_dialog_layout)
2981        # styles
2982        stylesheet = """
2983        QDialog {background-color: #F6F4F8;}
2984        QTableView {background-color: white;}
2985        """
2986        table_dialog.setStyleSheet(stylesheet)
2987        table_dialog.setWindowFlag(QtCore.Qt.WindowMaximizeButtonHint, True)
2988        table_dialog.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, True)
2989        table_dialog.setModal(True)
2990        table_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # disables editing of cells
2991        table_dialog.setWindowTitle("Distances of Structure Alignment")
2992        table_dialog.show()
2993
2994    # </editor-fold>
2995
2996    # <editor-fold desc="Manage page functions">
2997    def choose_manage_open_protein(self) -> None:
2998        """Shows the different configuration gui elements."""
2999        if self._view.ui.box_manage_choose_protein.currentText() != "":
3000            gui_elements_to_show = [
3001                self._view.ui.lbl_manage_choose_color,
3002                self._view.ui.box_manage_choose_color,
3003                self._view.ui.lbl_manage_choose_representation,
3004                self._view.ui.box_manage_choose_representation,
3005                self._view.ui.lbl_manage_choose_bg_color,
3006                self._view.ui.box_manage_choose_bg_color,
3007            ]
3008            gui_utils.show_gui_elements(gui_elements_to_show)
3009            tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3010            if (
3011                cmd.select(
3012                    name="disulfides",
3013                    selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3014                )
3015                > 0
3016            ):
3017                gui_elements_to_show = [
3018                    self._view.ui.lbl_disulfid_bond_1,
3019                    self._view.ui.lbl_disulfid_bond_2,
3020                    self._view.ui.btn_disulfid_bond_show,
3021                    self._view.ui.btn_disulfid_bond_hide,
3022                ]
3023                gui_utils.show_gui_elements(gui_elements_to_show)
3024        else:
3025            gui_elements_to_hide = [
3026                self._view.ui.lbl_manage_choose_color,
3027                self._view.ui.box_manage_choose_color,
3028                self._view.ui.lbl_manage_choose_representation,
3029                self._view.ui.box_manage_choose_representation,
3030                self._view.ui.lbl_manage_choose_bg_color,
3031                self._view.ui.box_manage_choose_bg_color,
3032                self._view.ui.lbl_disulfid_bond_1,
3033                self._view.ui.lbl_disulfid_bond_2,
3034                self._view.ui.btn_disulfid_bond_show,
3035                self._view.ui.btn_disulfid_bond_hide,
3036            ]
3037            gui_utils.hide_gui_elements(gui_elements_to_hide)
3038
3039    def choose_manage_color_selected_protein(self) -> None:
3040        """Sets the protein color."""
3041        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3042        tmp_protein = self._current_project.search_protein(tmp_input)
3043        tmp_protein.color_protein_in_pymol(
3044            self._view.ui.box_manage_choose_color.currentText(),
3045            f"/{tmp_protein.get_molecule_object()}",
3046        )
3047
3048    def choose_manage_representation(self) -> None:
3049        """Sets the representation."""
3050        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3051        tmp_protein = self._current_project.search_protein(tmp_input)
3052        tmp_selection = f"/{tmp_protein.get_molecule_object()}"
3053        if self._view.ui.box_manage_choose_representation.currentIndex() == 0:
3054            print("Please select a representation.")
3055            self._view.status_bar.showMessage("Please select a representation.")
3056        elif self._view.ui.box_manage_choose_representation.currentIndex() == 1:
3057            cmd.show("cartoon", tmp_selection)
3058            cmd.hide("ribbon", tmp_selection)
3059        elif self._view.ui.box_manage_choose_representation.currentIndex() == 2:
3060            cmd.show("ribbon", tmp_selection)
3061            cmd.hide("cartoon", tmp_selection)
3062        else:
3063            print("Missing implementation!")
3064
3065    def choose_manage_bg_color(self) -> None:
3066        """Sets the background color."""
3067        if self._view.ui.box_manage_choose_bg_color.currentIndex() == 0:
3068            print("Please select a background color.")
3069            self._view.status_bar.showMessage("Please select a background color.")
3070        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 1:
3071            cmd.bg_color("black")
3072        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 2:
3073            cmd.bg_color("white")
3074        else:
3075            print("Missing implementation!")
3076
3077    def show_disulfid_bonds_as_sticks(self) -> None:
3078        """Shows all disulfid bonds within the pymol session."""
3079        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3080        cmd.select(
3081            name="disulfides",
3082            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3083        )
3084        cmd.color(color="atomic", selection="disulfides and not elem C")
3085        cmd.set("valence", 0)  # this needs to be better implemented
3086        cmd.show("sticks", "disulfides")
3087        cmd.hide("sticks", "elem H")
3088
3089    def hide_disulfid_bonds_as_sticks(self) -> None:
3090        """Hides all disulfid bonds within the pymol session."""
3091        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3092        cmd.select(
3093            name="disulfides",
3094            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3095        )
3096        cmd.hide("sticks", "disulfides")
3097
3098    # </editor-fold>
3099
3100    # <editor-fold desc="Image page functions">
3101    def show_representation(self) -> None:
3102        """Sets the representation."""
3103        if self._view.ui.box_representation.currentIndex() == 0:
3104            self.main_window_state.image_page.representation = ""
3105            self._view.status_bar.showMessage("Please select a representation.")
3106        elif self._view.ui.box_representation.currentIndex() == 1:
3107            cmd.show("cartoon", "all")
3108            cmd.hide("ribbon", "all")
3109            self.main_window_state.image_page.representation = "cartoon"
3110        elif self._view.ui.box_representation.currentIndex() == 2:
3111            cmd.show("ribbon", "all")
3112            cmd.hide("cartoon", "all")
3113            self.main_window_state.image_page.representation = "ribbon"
3114        else:
3115            print("Missing implementation!")
3116
3117    def choose_bg_color(self) -> None:
3118        """Sets the background color."""
3119        if self._view.ui.box_bg_color.currentIndex() == 0:
3120            self.main_window_state.image_page.background_color = ""
3121            self._view.status_bar.showMessage("Please select a background color.")
3122        elif self._view.ui.box_bg_color.currentIndex() == 1:
3123            cmd.bg_color("black")
3124            self.main_window_state.image_page.background_color = "black"
3125        elif self._view.ui.box_bg_color.currentIndex() == 2:
3126            cmd.bg_color("white")
3127            self.main_window_state.image_page.background_color = "white"
3128        else:
3129            print("Missing implementation!")
3130
3131    def choose_renderer(self) -> None:
3132        """Sets the renderer."""
3133        if self._view.ui.box_renderer.currentIndex() == 0:
3134            self._view.status_bar.showMessage("Please select a renderer.")
3135            self._view.ui.cb_ray_tracing.hide()
3136            self._view.ui.label_26.hide()
3137        elif self._view.ui.box_renderer.currentIndex() == 1:
3138            self.renderer = "-1"
3139            self._view.ui.cb_ray_tracing.show()
3140            self._view.ui.label_26.show()
3141        elif self._view.ui.box_renderer.currentIndex() == 2:
3142            self.renderer = "0"
3143            self._view.ui.cb_ray_tracing.show()
3144            self._view.ui.label_26.show()
3145        else:
3146            print("Missing implementation!")
3147        self.main_window_state.image_page.renderer = self._view.ui.box_renderer.currentIndex()
3148
3149    def choose_ray_trace_mode(self) -> None:
3150        """Sets the ray-trace mode."""
3151        if self._view.ui.box_ray_trace_mode.currentIndex() == 0:
3152            self._view.status_bar.showMessage("Please select a Ray-Trace-Mode.")
3153        elif self._view.ui.box_ray_trace_mode.currentIndex() == 1:
3154            cmd.set("ray_trace_mode", 0)
3155        elif self._view.ui.box_ray_trace_mode.currentIndex() == 2:
3156            cmd.set("ray_trace_mode", 1)
3157        elif self._view.ui.box_ray_trace_mode.currentIndex() == 3:
3158            cmd.set("ray_trace_mode", 2)
3159        elif self._view.ui.box_ray_trace_mode.currentIndex() == 4:
3160            cmd.set("ray_trace_mode", 3)
3161        else:
3162            print("Missing implementation!")
3163        self.main_window_state.image_page.ray_trace_mode = self._view.ui.box_ray_trace_mode.currentIndex()
3164
3165    def choose_ray_texture(self) -> None:
3166        """Sets the ray texture."""
3167        if self._view.ui.box_ray_texture.currentIndex() == 0:
3168            print("Please select a Ray Texture.")
3169            self._view.status_bar.showMessage("Please select a Ray Texture.")
3170        elif self._view.ui.box_ray_texture.currentIndex() == 1:
3171            cmd.set("ray_texture", 0)
3172        elif self._view.ui.box_ray_texture.currentIndex() == 2:
3173            cmd.set("ray_texture", 1)
3174        elif self._view.ui.box_ray_texture.currentIndex() == 3:
3175            cmd.set("ray_texture", 2)
3176        elif self._view.ui.box_ray_texture.currentIndex() == 4:
3177            cmd.set("ray_texture", 3)
3178        elif self._view.ui.box_ray_texture.currentIndex() == 5:
3179            cmd.set("ray_texture", 4)
3180        elif self._view.ui.box_ray_texture.currentIndex() == 6:
3181            cmd.set("ray_texture", 5)
3182        else:
3183            print("Missing implementation!")
3184        self.main_window_state.image_page.ray_texture = self._view.ui.box_ray_texture.currentIndex()
3185
3186    def decide_ray_tracing(self) -> None:
3187        """Sets the ray-tracing options."""
3188        print(self._view.ui.cb_ray_tracing.isChecked())
3189        if self._view.ui.cb_ray_tracing.isChecked():
3190            self._view.ui.cb_transparent_bg.hide()
3191            self._view.ui.label_23.hide()
3192            self._view.ui.box_renderer.setEnabled(False)
3193            self._view.ui.label_10.show()
3194            self._view.ui.box_ray_trace_mode.show()
3195            self._view.ui.label_14.show()
3196            self._view.ui.box_ray_texture.show()
3197            cmd.set("ray_opaque_background", "off")
3198        else:
3199            self._view.ui.cb_transparent_bg.show()
3200            self._view.ui.label_23.show()
3201            self._view.ui.box_renderer.setEnabled(True)
3202            self._view.ui.label_10.hide()
3203            self._view.ui.box_ray_trace_mode.hide()
3204            self._view.ui.label_14.hide()
3205            self._view.ui.box_ray_texture.hide()
3206        self.main_window_state.image_page.ray_tracing = self._view.ui.cb_ray_tracing.isChecked()
3207
3208    def decide_transparent_bg(self) -> None:
3209        """Sets the transparent background."""
3210        if self._view.ui.cb_transparent_bg.isChecked():
3211            cmd.set("opaque_background", "off")
3212        else:
3213            cmd.set("opaque_background", "on")
3214        self.main_window_state.image_page.transparent_background = self._view.ui.cb_transparent_bg.isChecked()
3215
3216    @staticmethod
3217    def update_scene() -> None:
3218        """Updates the current selected PyMOL scene."""
3219        cmd.scene(key="auto", action="update")
3220
3221    def save_scene(self) -> None:
3222        """Saves the current view as a new PyMOL scene."""
3223        # returns tuple with (name, bool)
3224        scene_name = QtWidgets.QInputDialog.getText(self._view, "Save Scene", "Enter scene name:")
3225        if scene_name[1]:
3226            cmd.scene(key=scene_name[0], action="append")
3227
3228    def post_preview_image(self) -> None:
3229        """Hides the block box of the preview process."""
3230        self.block_box_uni.hide()
3231        self.block_box_uni.destroy(True)
3232        self._view.status_bar.showMessage("Finished preview of ray-traced image.")
3233        QtWidgets.QApplication.restoreOverrideCursor()
3234
3235    def preview_image(self) -> None:
3236        """Previews the image."""
3237        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3238        if self._view.ui.cb_ray_tracing.isChecked():
3239            self._view.status_bar.showMessage("Preview ray-traced image ...")
3240            # <editor-fold desc="Worker setup">
3241            # --Begin: worker setup
3242            self.tmp_thread = QtCore.QThread()
3243            self.tmp_worker = task_workers.PreviewRayImageWorker(self.renderer)
3244            self.tmp_thread = task_workers.setup_worker_for_work(
3245                self.tmp_thread,
3246                self.tmp_worker,
3247                self.display_view_page,
3248            )
3249            self.tmp_worker.finished.connect(self.post_preview_image)
3250            self.tmp_thread.start()
3251            # --End: worker setup
3252
3253            # </editor-fold>
3254            gui_utils.setup_standard_block_box(
3255                self.block_box_uni,
3256                "Preview ray-trace image",
3257                "Creating preview for the ray-traced image ...",
3258            )
3259            self.block_box_uni.exec_()
3260        else:
3261            self._view.status_bar.showMessage("Preview draw image ...")
3262            cmd.draw(2400, 2400)
3263            self._view.status_bar.showMessage("Finished preview of drawn image.")
3264            QtWidgets.QApplication.restoreOverrideCursor()
3265
3266    def post_save_image(self) -> None:
3267        """Displays a message box which informs that the process has finished."""
3268        self.block_box_uni.hide()
3269        self.block_box_uni.destroy(True)
3270        self._view.status_bar.showMessage("Finished image creation.")
3271        QtWidgets.QApplication.restoreOverrideCursor()
3272        basic_boxes.ok("Finished image creation", "The image has been created.", QtWidgets.QMessageBox.Information)
3273
3274    def save_image(self) -> None:
3275        """Saves the image as a png file."""
3276        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3277        if self._view.ui.cb_ray_tracing.isChecked():
3278            save_dialog = QtWidgets.QFileDialog()
3279            try:
3280                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3281                if full_file_name == ("", ""):
3282                    tools.quick_log_and_display(
3283                        "info",
3284                        "No file has been selected.",
3285                        self._view.status_bar,
3286                        "No file has been selected.",
3287                    )
3288                    return
3289                self._view.status_bar.showMessage("Creating ray-traced image ...")
3290
3291                # <editor-fold desc="Worker setup">
3292                # --Begin: worker setup
3293                self.tmp_thread = QtCore.QThread()
3294                self.tmp_worker = task_workers.SaveRayImageWorker(self.renderer, full_file_name[0])
3295                self.tmp_thread = task_workers.setup_worker_for_work(
3296                    self.tmp_thread,
3297                    self.tmp_worker,
3298                    self.display_view_page,
3299                )
3300                self.tmp_worker.finished.connect(self.post_save_image)
3301                self.tmp_thread.start()
3302                # --End: worker setup
3303
3304                # </editor-fold>
3305                gui_utils.setup_standard_block_box(
3306                    self.block_box_uni,
3307                    "Save ray-trace image",
3308                    "Creating the ray-traced image ...",
3309                )
3310                self.block_box_uni.exec_()
3311
3312                # cmd.ray(2400, 2400, renderer=int(self.renderer))
3313                # cmd.png(full_file_name[0], dpi=300)
3314
3315            except FileExistsError:
3316                tools.quick_log_and_display(
3317                    "error",
3318                    "File exists already.",
3319                    self._view.status_bar,
3320                    "File exists already.",
3321                )
3322            except pymol.CmdException:
3323                tools.quick_log_and_display(
3324                    "error",
3325                    "Unexpected Error from PyMOL while saving the " "an image",
3326                    self._view.status_bar,
3327                    "Unexpected Error from PyMOL",
3328                )
3329        else:
3330            save_dialog = QtWidgets.QFileDialog()
3331            try:
3332                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3333                if full_file_name == ("", ""):
3334                    tools.quick_log_and_display(
3335                        "info",
3336                        "No file has been selected.",
3337                        self._view.status_bar,
3338                        "No file has been selected.",
3339                    )
3340                    return
3341                self._view.status_bar.showMessage("Creating draw image ...")
3342                cmd.draw(2400, 2400)
3343                cmd.png(full_file_name[0], dpi=300)
3344                self._view.status_bar.showMessage("Finished image creation.")
3345                basic_boxes.ok(
3346                    "Finished image creation",
3347                    "The image has been created.",
3348                    QtWidgets.QMessageBox.Information,
3349                )
3350            except FileExistsError:
3351                tools.quick_log_and_display(
3352                    "error",
3353                    "File exists already.",
3354                    self._view.status_bar,
3355                    "File exists already.",
3356                )
3357            except pymol.CmdException:
3358                tools.quick_log_and_display(
3359                    "error",
3360                    "Unexpected Error from PyMOL while saving the " "an image",
3361                    self._view.status_bar,
3362                    "Unexpected Error from PyMOL",
3363                )
3364            finally:
3365                QtWidgets.QApplication.restoreOverrideCursor()
3366
3367    # </editor-fold>
3368
3369    # <editor-fold desc="Hotspots page functions">
3370    def open_protein_for_hotspots(self) -> None:
3371        """Loads the selected protein's pymol session."""
3372        self._view.wait_spinner.start()
3373        try:
3374            tmp_name = self._view.ui.list_hotspots_choose_protein.currentItem().text()
3375        except AttributeError:
3376            self._view.wait_spinner.stop()
3377            return
3378        if self._view.ui.list_hotspots_choose_protein.currentItem().text() != "":
3379            tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
3380            self._active_task = tasks.Task(
3381                target=main_presenter_async.open_protein_for_hotspots,
3382                args=(
3383                    tmp_name,
3384                    self._current_project,
3385                    self.current_session,
3386                ),
3387                post_func=self.__await_open_protein_for_hotspots,
3388            )
3389            self._active_task.start()
3390            self.update_status("Loading PyMOL session ...")
3391        else:
3392            self._view.wait_spinner.stop()
3393            self.update_status(self._workspace_status)
3394
3395    def __await_open_protein_for_hotspots(self, result: tuple) -> None:
3396        _, is_protein, is_protein_pair, self.current_session = result
3397        if is_protein and not is_protein_pair:
3398            gui_elements_to_show = [
3399                self._view.ui.lbl_hotspots_resi_show,
3400                self._view.ui.btn_hotspots_resi_show,
3401                self._view.ui.lbl_hotspots_resi_hide,
3402                self._view.ui.btn_hotspots_resi_hide,
3403                self._view.ui.lbl_hotspots_resi_zoom,
3404                self._view.ui.btn_hotspots_resi_zoom,
3405                self._view.ui.btn_manage_session,
3406            ]
3407            gui_utils.show_gui_elements(gui_elements_to_show)
3408        elif is_protein_pair and not is_protein:
3409            gui_elements_to_show = [
3410                self._view.ui.lbl_hotspots_resi_show,
3411                self._view.ui.btn_hotspots_resi_show,
3412                self._view.ui.lbl_hotspots_resi_hide,
3413                self._view.ui.btn_hotspots_resi_hide,
3414                self._view.ui.lbl_hotspots_resi_zoom,
3415                self._view.ui.btn_hotspots_resi_zoom,
3416                self._view.ui.btn_manage_session,
3417            ]
3418            gui_utils.show_gui_elements(gui_elements_to_show)
3419        else:
3420            pass
3421        self._view.wait_spinner.stop()
3422        self.update_status(self._workspace_status)
3423
3424    @staticmethod
3425    def hide_resi_sticks() -> None:
3426        """Hides the balls and sticks representation of the pymol selection."""
3427        session_util.check_if_sele_is_empty()
3428        cmd.hide(representation="sticks", selection="sele")
3429
3430    @staticmethod
3431    def show_resi_sticks() -> None:
3432        """Shows the pymol selection as sticks."""
3433        session_util.check_if_sele_is_empty()
3434        cmd.show(representation="sticks", selection="sele and not hydrogens")
3435        cmd.select(name="sele", selection="sele and not hydrogens")
3436        cmd.color(color="atomic", selection="sele and not elem C")
3437        cmd.set("valence", 0)  # this needs to be better implemented
3438
3439    @staticmethod
3440    def zoom_resi_position() -> None:
3441        """Zooms to the pymol selection."""
3442        session_util.check_if_sele_is_empty()
3443        cmd.zoom(selection="sele", buffer=8.0, state=0, complete=0)
3444
3445    # </editor-fold>
3446
3447    # </editor-fold>
3448
3449    # <editor-fold desc="GUI related methods">
3450
3451    # <editor-fold desc="GUI page management functions">
3452    def _create_batch_analysis_management(self) -> None:
3453        """Creates a list of gui stages."""
3454        # gui element management
3455        tmp_stages = [
3456            # add a prot analysis: stage 0
3457            stage.Stage(
3458                {
3459                    "label_batch_analysis_overview": self._view.ui.lbl_analysis_batch_overview,
3460                    "box_protein_structure_1": self._view.ui.list_analysis_batch_overview,
3461                },
3462                {
3463                    "add_button": self._view.ui.btn_analysis_batch_add,
3464                    "remove_button": self._view.ui.btn_analysis_batch_remove,
3465                },
3466            ),
3467            # choose protein structures: stage 1
3468            stage.Stage(
3469                {
3470                    "label_protein_structure_1": self._view.ui.lbl_analysis_batch_prot_struct_1,
3471                    "box_protein_structure_1": self._view.ui.box_analysis_batch_prot_struct_1,
3472                    "label_vs": self._view.ui.lbl_analysis_batch_vs,
3473                    "label_protein_structure_2": self._view.ui.lbl_analysis_batch_prot_struct_2,
3474                    "box_protein_structure_2": self._view.ui.box_analysis_batch_prot_struct_2,
3475                },
3476                {
3477                    "next_button": self._view.ui.btn_analysis_batch_next,
3478                    "back_button": self._view.ui.btn_analysis_batch_back,
3479                },
3480            ),
3481            # choose chains from prot structure 1: stage 2
3482            stage.Stage(
3483                {
3484                    "label_protein_structure_1_chains": self._view.ui.lbl_analysis_batch_ref_chains,
3485                    "list_protein_structure_1_chains": self._view.ui.list_analysis_batch_ref_chains,
3486                },
3487                {
3488                    "back_button": self._view.ui.btn_analysis_batch_back_2,
3489                    "next_button": self._view.ui.btn_analysis_batch_next_2,
3490                },
3491            ),
3492            # choose chains from prot structure 2: stage 3
3493            stage.Stage(
3494                {
3495                    "label_protein_structure_2_chains": self._view.ui.lbl_analysis_batch_model_chains,
3496                    "list_protein_structure_2_chains": self._view.ui.list_analysis_batch_model_chains,
3497                },
3498                {
3499                    "back_button": self._view.ui.btn_analysis_batch_back_3,
3500                    "next_button": self._view.ui.btn_analysis_batch_next_3,
3501                },
3502            ),
3503            # start batch run: stage 4
3504            stage.Stage(
3505                {
3506                    "label_images": self._view.ui.lbl_analysis_batch_images,
3507                    "checkbox_images": self._view.ui.cb_analysis_batch_images,
3508                },
3509                {
3510                    "start_button": self._view.ui.btn_analysis_batch_start,
3511                },
3512            ),
3513        ]
3514        self.batch_analysis_management = gui_page_management.GuiPageManagement(tmp_stages)
3515
3516    def _create_results_management(self) -> None:
3517        """Creates a list of gui stages."""
3518        # gui element management
3519        tmp_stages = [
3520            # choose protein structures: stage 0
3521            stage.Stage(
3522                {
3523                    "label_analysis_options": self._view.ui.lbl_results_analysis_options,
3524                    "box_results_analysis_options": self._view.ui.cb_results_analysis_options,
3525                },
3526                {
3527                    "": None,
3528                },
3529            ),
3530            # choose chains from prot structure 1: stage 1
3531            stage.Stage(
3532                {
3533                    "label_results_rmsd": self._view.ui.lbl_results_rmsd,
3534                    "text_results_rmsd": self._view.ui.txt_results_rmsd,
3535                    "label_color_rmsd": self._view.ui.lbl_color_rmsd,
3536                    "button_color_rmsd": self._view.ui.btn_color_rmsd,
3537                    "label_results_aligned_residues": self._view.ui.lbl_results_aligned_residues,
3538                    "text_results_aligned_residues": self._view.ui.txt_results_aligned_residues,
3539                    "label_results_distance_plot": self._view.ui.lbl_results_distance_plot,
3540                    "button_view_distance_plot": self._view.ui.btn_view_distance_plot,
3541                    "label_results_distance_histogram": self._view.ui.lbl_results_distance_histogram,
3542                    "button_view_distance_histogram": self._view.ui.btn_view_distance_histogram,
3543                    "label_results_distance_table": self._view.ui.lbl_results_distance_table,
3544                    "button_view_distance_table": self._view.ui.btn_view_distance_table,
3545                    "label_results_structure_alignment": self._view.ui.lbl_results_structure_alignment,
3546                    "button_view_struct_alignment": self._view.ui.btn_view_struct_alignment,
3547                    "label_results_interest_regions": self._view.ui.lbl_results_interest_regions,
3548                    "list_results_interest_regions": self._view.ui.list_results_interest_regions,
3549                    "button_results_interest_regions": self._view.ui.btn_view_interesting_region,
3550                },
3551                {
3552                    "": None,
3553                },
3554            ),
3555        ]
3556        self.results_management = gui_page_management.GuiPageManagement(tmp_stages)
3557
3558    # </editor-fold>
3559
3560    # <editor-fold desc="Page init functions">
3561    def _init_fill_combo_boxes(self) -> None:
3562        """Fills all combo boxes of the plugin."""
3563        item_list_representation = [
3564            "",
3565            "cartoon",
3566            "ribbon",
3567        ]
3568        gui_utils.fill_combo_box(self._view.ui.box_representation, item_list_representation)
3569        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_representation, item_list_representation)
3570        # combo box BgColor
3571        item_list_bg_color = [
3572            "",
3573            "black",
3574            "white",
3575        ]
3576        gui_utils.fill_combo_box(self._view.ui.box_bg_color, item_list_bg_color)
3577        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_bg_color, item_list_bg_color)
3578        # combo box Renderer
3579        item_list_renderer = [
3580            "",
3581            "default renderer",
3582            "PyMOL internal renderer",
3583        ]
3584        gui_utils.fill_combo_box(self._view.ui.box_renderer, item_list_renderer)
3585        # combo box RayTraceMode
3586        item_list_ray_trace_mode = [
3587            "",
3588            "normal color",
3589            "normal color + black outline",
3590            "black outline only",
3591            "quantized color + black outline",
3592        ]
3593        gui_utils.fill_combo_box(self._view.ui.box_ray_trace_mode, item_list_ray_trace_mode)
3594        # combo box Ray Texture
3595        item_list_ray_texture = [
3596            "",
3597            "None",
3598            "Matte 1",
3599            "Matte 2",
3600            "Swirl 1",
3601            "Fiber",
3602        ]
3603        gui_utils.fill_combo_box(self._view.ui.box_ray_texture, item_list_ray_texture)
3604        # combo box protein Colors
3605        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_color, constants.PYMOL_COLORS)
3606
3607    def _init_new_page(self) -> None:
3608        """Clears all text fields and hides everything which is needed."""
3609        self._view.ui.txt_new_project_name.clear()
3610        self._view.ui.txt_new_choose_reference.clear()
3611        self._view.ui.lbl_new_status_project_name.setText("")
3612        self._view.ui.lbl_new_status_choose_reference.setText("")
3613        self._view.ui.cb_new_add_reference.setCheckState(0)
3614        self._view.ui.btn_new_create_project.setEnabled(False)
3615        styles.color_button_not_ready(self._view.ui.btn_new_create_project)
3616
3617    def _init_use_page(self) -> None:
3618        """Clears all text fields and hides everything which is needed."""
3619        gui_elements = [
3620            self._view.ui.lbl_use_search,
3621            self._view.ui.lbl_use_status_search,
3622            self._view.ui.txt_use_search,
3623            self._view.ui.btn_use_add_available_protein_structures,
3624            self._view.ui.lbl_use_available_protein_structures,
3625            self._view.ui.list_use_available_protein_structures,
3626            self._view.ui.btn_use_remove_selected_protein_structures,
3627            self._view.ui.lbl_use_selected_protein_structures,
3628            self._view.ui.list_use_selected_protein_structures,
3629            self._view.ui.btn_use_back,
3630            self._view.ui.btn_use_create_new_project,
3631            self._view.ui.lbl_use_new_project,
3632        ]
3633        gui_utils.hide_gui_elements(gui_elements)
3634        self._view.ui.txt_use_project_name.clear()
3635        self._view.ui.lbl_use_status_project_name.setText("")
3636        self._view.ui.txt_use_search.clear()
3637        self._view.ui.lbl_use_status_search.setText("")
3638        self._view.ui.list_use_available_protein_structures.clear()
3639        self._view.ui.list_use_selected_protein_structures.clear()
3640        self._view.ui.list_use_existing_projects.clear()
3641        self._view.ui.btn_use_next.setEnabled(False)
3642        self.hide_protein_selection_for_use()
3643
3644    def _init_edit_page(self) -> None:
3645        """Clears all text fields and hides everything which is needed."""
3646        self._view.ui.list_edit_project_proteins.clear()
3647        gui_elements_to_hide = [
3648            self._view.ui.lbl_edit_clean_new_prot,
3649            self._view.ui.btn_edit_clean_new_prot,
3650            self._view.ui.lbl_edit_clean_update_prot,
3651            self._view.ui.btn_edit_clean_update_prot,
3652            self._view.ui.label_12,
3653            self._view.ui.btn_edit_project_delete,
3654            self._view.ui.label_15,
3655            self._view.ui.btn_edit_protein_rename,
3656            self._view.ui.btn_edit_project_save,
3657            self._view.ui.label_13,
3658        ]
3659        gui_utils.hide_gui_elements(gui_elements_to_hide)
3660        gui_utils.fill_list_view_with_protein_names(self._current_project, self._view.ui.list_edit_project_proteins)
3661        # self.project_scanner.scan_project_for_valid_proteins(self._view.ui.list_edit_project_proteins)
3662
3663    def _init_sequence_vs_pdb_page(self) -> None:
3664        """Clears all text fields and hides everything which is needed."""
3665        self._view.ui.list_s_v_p_ref_chains.clear()
3666        # # sets up defaults: Prediction + Analysis
3667        #
3668        # #self._view.ui.label_18.hide()
3669        # #self._view.ui.txt_prediction_project_name.hide()
3670        # #self._view.ui.lbl_prediction_status_project_name.hide()
3671        # # stage 1
3672        # self._view.ui.lbl_prediction_status_project_name.setText("")
3673        #
3674        # #self._view.ui.list_widget_projects.hide()
3675        # #self._view.ui.btn_prediction_next_1.hide()
3676        # # stage 2
3677        # self._view.ui.lbl_prediction_load_reference.hide()
3678        # self._view.ui.txt_prediction_load_reference.clear()
3679        # self._view.ui.txt_prediction_load_reference.hide()
3680        # self._view.ui.lbl_prediction_status_load_reference.setText("")
3681        # self._view.ui.btn_prediction_back_2.setEnabled(False)
3682        # self._view.ui.btn_prediction_back_2.hide()
3683        # self._view.ui.btn_prediction_next_2.setEnabled(False)
3684        # self._view.ui.btn_prediction_next_2.hide()
3685        #
3686        # # stage 3
3687        # self._view.ui.lbl_prediction_ref_chains.hide()
3688        # self._view.ui.list_widget_ref_chains.hide()
3689        # # TO-DO: stylesheet needs to be integrated into the styles.css
3690        # self._view.ui.list_widget_ref_chains.setStyleSheet("border-style: solid;"
3691        #                                              "border-width: 2px;"
3692        #                                              "border-radius: 8px;"
3693        #                                              "border-color: #DCDBE3;")
3694        # self._view.ui.list_widget_ref_chains.setSelectionMode(PyQt5.QtWidgets.QAbstractItemView.ExtendedSelection)
3695        # self._view.ui.btn_prediction_back_3.setEnabled(False)
3696        # self._view.ui.btn_prediction_back_3.hide()
3697        # self._view.ui.btn_prediction_start.setEnabled(False)
3698        # self._view.ui.btn_prediction_start.hide()
3699        # # TO-DO: needs to be removed if model chains are implemented at the right spot
3700        # self._view.ui.lbl_prediction_model_chains.hide()
3701        # self._view.ui.txt_prediction_chain_model.hide()
3702
3703    def _init_results_page(self) -> None:
3704        """Clears all text fields and hides everything which is needed."""
3705        # stage 1
3706        self._view.ui.list_results_interest_regions.clear()
3707        self._view.ui.txt_results_rmsd.clear()
3708        self._view.ui.txt_results_aligned_residues.clear()
3709
3710    def _init_analysis_image_page(self) -> None:
3711        """Clears all text fields and hides everything which is needed."""
3712        self._view.ui.list_analysis_images_struct_analysis.setEnabled(True)
3713        self._view.ui.list_analysis_images_creation_struct_analysis.setEnabled(True)
3714        self.display_image_analysis_page()
3715
3716    def _init_image_page(self) -> None:
3717        """Hides everything which is needed."""
3718        self._view.ui.label_10.hide()
3719        self._view.ui.box_ray_trace_mode.hide()
3720        self._view.ui.label_14.hide()
3721        self._view.ui.box_ray_texture.hide()
3722
3723    def _init_batch_analysis_page(self) -> None:
3724        """Clears all text fields and hides everything which is needed."""
3725        # sets up defaults: Batch
3726        self.batch_analysis_management.show_stage_x(0)
3727        self._view.ui.list_analysis_batch_overview.clear()
3728        self._view.ui.btn_analysis_batch_remove.hide()
3729
3730    def _init_all_pages(self) -> None:
3731        """Collection of all init methods to reset all page defaults."""
3732        self._init_local_pred_mono_page()
3733        self._init_local_pred_multi_page()
3734        self._init_mono_pred_analysis_page()
3735        self._init_multi_pred_analysis_page()
3736        self._init_sequence_vs_pdb_page()
3737        self._init_batch_analysis_page()
3738        self._init_analysis_image_page()
3739        self._init_results_page()
3740        self._init_image_page()
3741
3742    # </editor-fold>
3743
3744    # <editor-fold desc="Display page functions">
3745    def display_home_page(self) -> None:
3746        """Displays the homepage of the plugin."""
3747        if self.is_distance_plot_open:
3748            self.distance_plot_dialog.close()
3749            self.is_distance_plot_open = False
3750        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 0, "Home")
3751
3752    def display_job_analysis_page(self) -> None:
3753        """Displays the job analysis work area."""
3754        self._view.ui.list_analysis_batch_ref_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3755        self._view.ui.list_analysis_batch_model_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3756        # regular work area opening
3757        self._init_batch_analysis_page()
3758        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 4, "Structure Analysis")
3759        self.last_sidebar_button = styles.color_sidebar_buttons(
3760            self.last_sidebar_button,
3761            self._view.ui.btn_batch_analysis_page,
3762        )
3763
3764    def display_results_page(self) -> None:
3765        """Displays the results work area."""
3766        if self.is_distance_plot_open:
3767            self.distance_plot_dialog.close()
3768            self.is_distance_plot_open = False
3769        results = []
3770        results.insert(0, "")
3771
3772        for tmp_protein_pair in self._current_project.protein_pairs:
3773            results.append(tmp_protein_pair.name)
3774            if tmp_protein_pair.name == self.results_name:
3775                pass
3776        self._view.ui.cb_results_analysis_options.clear()
3777        gui_utils.fill_combo_box(self._view.ui.cb_results_analysis_options, results)
3778
3779        desired_string: str = self.main_window_state.results_page.results_name
3780        # Find the index of the string in the combo box
3781        index = self._view.ui.cb_results_analysis_options.findText(desired_string)
3782        # Set the current index of the combo box
3783        if index != -1:
3784            self._view.ui.cb_results_analysis_options.setCurrentIndex(index)
3785        else:
3786            print(f"String '{desired_string}' not found in the combo box.")
3787
3788        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 5, "Results")
3789        self.last_sidebar_button = styles.color_sidebar_buttons(
3790            self.last_sidebar_button,
3791            self._view.ui.btn_results_page,
3792        )
3793
3794    def display_image_page(self) -> None:
3795        """Displays the image work area."""
3796        if self.is_distance_plot_open:
3797            self.distance_plot_dialog.close()
3798            self.is_distance_plot_open = False
3799        self._init_image_page()
3800
3801        if self.main_window_state.image_page.transparent_background:
3802            self._view.ui.cb_transparent_bg.setChecked(True)
3803        else:
3804            self._view.ui.cb_transparent_bg.setChecked(False)
3805        if self.main_window_state.image_page.ray_tracing:
3806            self._view.ui.cb_ray_tracing.setChecked(True)
3807        else:
3808            self._view.ui.cb_ray_tracing.setChecked(False)
3809        try:
3810            self._view.ui.box_representation.setCurrentIndex(
3811                self._view.ui.box_representation.findText(self.main_window_state.image_page.representation),
3812            )
3813            self._view.ui.box_bg_color.setCurrentIndex(
3814                self._view.ui.box_bg_color.findText(self.main_window_state.image_page.background_color),
3815            )
3816            self._view.ui.box_renderer.setCurrentIndex(self.main_window_state.image_page.renderer)
3817            self._view.ui.box_ray_trace_mode.setCurrentIndex(self.main_window_state.image_page.ray_trace_mode)
3818            self._view.ui.box_ray_texture.setCurrentIndex(self.main_window_state.image_page.ray_texture)
3819        except IndexError:
3820            constants.PYSSA_LOGGER.error("An option is invalid.")
3821
3822        if self._view.ui.box_renderer.currentText() == "":
3823            self._view.ui.cb_ray_tracing.hide()
3824            self._view.ui.label_26.hide()
3825        else:
3826            self._view.ui.cb_ray_tracing.show()
3827            self._view.ui.label_26.show()
3828
3829        if self._view.ui.cb_ray_tracing.isChecked():
3830            self._view.ui.label_10.show()
3831            self._view.ui.box_ray_trace_mode.show()
3832            self._view.ui.label_14.show()
3833            self._view.ui.box_ray_texture.show()
3834        else:
3835            self._view.ui.label_10.hide()
3836            self._view.ui.box_ray_trace_mode.hide()
3837            self._view.ui.label_14.hide()
3838            self._view.ui.box_ray_texture.hide()
3839
3840        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_image_page)
3841        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 6, "Image")
3842
3843    def display_new_page(self) -> None:
3844        """Displays the new project work area."""
3845        self._init_new_page()
3846        self._view.ui.list_new_projects.clear()
3847        # pre-process
3848        gui_elements_to_hide = [
3849            self._view.ui.lbl_new_choose_reference,
3850            self._view.ui.txt_new_choose_reference,
3851            self._view.ui.btn_new_choose_reference,
3852        ]
3853        gui_utils.hide_gui_elements(gui_elements_to_hide)
3854        self._view.status_bar.showMessage(self._workspace_label.text())
3855        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_new_projects)
3856        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 7, "Create new project")
3857        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_new_page)
3858
3859    def display_open_page(self) -> None:
3860        """Displays the open project work area."""
3861        self._view.ui.txt_open_search.clear()
3862        self._view.ui.txt_open_selected_project.clear()
3863        if safeguard.Safeguard.check_filepath(self._workspace_path):
3864            self._view.ui.list_open_projects.clear()
3865            # pre-process
3866            self._view.status_bar.showMessage(self._workspace_label.text())
3867            try:
3868                tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_open_projects)
3869            except PermissionError:
3870                gui_utils.error_dialog_settings(
3871                    "The settings file is corrupted. Please restore the settings!",
3872                    "",
3873                    self._application_settings,
3874                )
3875                self.display_home_page()
3876                return
3877            tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 8, "Open existing project")
3878            self.last_sidebar_button = styles.color_sidebar_buttons(
3879                self.last_sidebar_button,
3880                self._view.ui.btn_open_page,
3881            )
3882        else:
3883            gui_utils.error_dialog_settings(
3884                "The settings file is corrupted. Please restore the settings!",
3885                "",
3886                self._application_settings,
3887            )
3888            self.display_home_page()
3889
3890    def display_delete_page(self) -> None:
3891        """Displays the "delete" project work area."""
3892        self._view.ui.txt_delete_search.clear()
3893        self._view.ui.txt_delete_selected_projects.clear()
3894        self._view.ui.list_delete_projects.clear()
3895        # pre-process
3896        self._view.status_bar.showMessage(self._workspace_label.text())
3897        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
3898        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 9, "Delete existing project")
3899        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_delete_page)
3900
3901    def display_edit_page(self) -> None:
3902        """Displays the edit project page."""
3903        if self.is_distance_plot_open:
3904            self.distance_plot_dialog.close()
3905            self.is_distance_plot_open = False
3906        # pre-process
3907        self._view.status_bar.showMessage(self._workspace_label.text())
3908        self._init_edit_page()
3909        tools.switch_page(
3910            self._view.ui.stackedWidget,
3911            self._view.ui.lbl_page_title,
3912            13,
3913            "Edit proteins of current project",
3914        )
3915        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_edit_page)
3916        if len(self._view.ui.list_edit_project_proteins) >= 2:
3917            self._view.ui.btn_edit_existing_protein_struct.hide()
3918            self._view.ui.lbl_edit_existing_protein_struct.hide()
3919        else:
3920            self._view.ui.btn_edit_existing_protein_struct.show()
3921            self._view.ui.lbl_edit_existing_protein_struct.show()
3922
3923    def display_hotspots_page(self) -> None:
3924        """Displays the hotspots page."""
3925        if self.is_distance_plot_open:
3926            self.distance_plot_dialog.close()
3927            self.is_distance_plot_open = False
3928        try:
3929            print(self._view.ui.list_hotspots_choose_protein.currentItem().text())
3930        except AttributeError:
3931            self._view.ui.list_hotspots_choose_protein.clear()
3932            gui_elements_to_hide = [
3933                self._view.ui.lbl_hotspots_resi_no,
3934                self._view.ui.sp_hotspots_resi_no,
3935                self._view.ui.lbl_hotspots_resi_show,
3936                self._view.ui.btn_hotspots_resi_show,
3937                self._view.ui.lbl_hotspots_resi_hide,
3938                self._view.ui.btn_hotspots_resi_hide,
3939                self._view.ui.lbl_hotspots_resi_zoom,
3940                self._view.ui.btn_hotspots_resi_zoom,
3941            ]
3942            gui_utils.hide_gui_elements(gui_elements_to_hide)
3943            gui_utils.fill_list_view_with_protein_names(
3944                self._current_project,
3945                self._view.ui.list_hotspots_choose_protein,
3946            )
3947            gui_utils.fill_list_view_with_protein_pair_names(
3948                self._current_project,
3949                self._view.ui.list_hotspots_choose_protein,
3950            )
3951        # self.project_scanner.scan_project_for_valid_proteins(self._view.ui.list_hotspots_choose_protein)
3952        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 18, "Hotspots")
3953        self.last_sidebar_button = styles.color_sidebar_buttons(
3954            self.last_sidebar_button,
3955            self._view.ui.btn_hotspots_page,
3956        )
3957
3958    def display_manage_pymol_session(self) -> None:
3959        """Displays the manage pymol session page."""
3960        if self.is_distance_plot_open:
3961            self.distance_plot_dialog.close()
3962            self.is_distance_plot_open = False
3963        self._view.ui.box_manage_choose_protein.clear()
3964        pymol_objs = cmd.get_object_list()
3965        pymol_objs.insert(0, "")
3966        for tmp_object in pymol_objs:
3967            self._view.ui.box_manage_choose_protein.addItem(tmp_object)
3968        self._view.ui.box_manage_choose_protein.setCurrentIndex(
3969            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_PROTEIN][0],
3970        )
3971        self._view.ui.box_manage_choose_color.setCurrentIndex(
3972            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_COLOR][0],
3973        )
3974        self._view.ui.box_manage_choose_representation.setCurrentIndex(
3975            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_REPRESENTATION][0],
3976        )
3977        self._view.ui.box_manage_choose_bg_color.setCurrentIndex(
3978            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_BG_COLOR][0],
3979        )
3980        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 24, "Manage PyMOL session")
3981        self.last_sidebar_button = styles.color_sidebar_buttons(
3982            self.last_sidebar_button,
3983            self._view.ui.btn_manage_session,
3984        )
3985        gui_elements_to_hide = [
3986            self._view.ui.lbl_manage_choose_color,
3987            self._view.ui.box_manage_choose_color,
3988            self._view.ui.lbl_manage_choose_representation,
3989            self._view.ui.box_manage_choose_representation,
3990            self._view.ui.lbl_manage_choose_bg_color,
3991            self._view.ui.box_manage_choose_bg_color,
3992            self._view.ui.lbl_disulfid_bond_1,
3993            self._view.ui.lbl_disulfid_bond_2,
3994            self._view.ui.btn_disulfid_bond_show,
3995            self._view.ui.btn_disulfid_bond_hide,
3996        ]
3997        gui_utils.hide_gui_elements(gui_elements_to_hide)
3998
3999    # </editor-fold>
4000
4001    # <editor-fold desc="New project">
4002    def show_add_reference(self) -> None:
4003        """Shows the reference input section."""
4004        # checkbox is checked
4005        self._view.ui.cb_new_add_reference.checkState()
4006        if self._view.ui.cb_new_add_reference.checkState() == 2:
4007            self._view.ui.txt_new_choose_reference.clear()
4008            self._view.ui.txt_new_choose_reference.setStyleSheet("background-color: white")
4009            self._view.ui.lbl_new_choose_reference.show()
4010            self._view.ui.txt_new_choose_reference.show()
4011            self._view.ui.btn_new_choose_reference.show()
4012            self._view.ui.btn_new_create_project.setEnabled(False)
4013            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4014            # check internet connectivity
4015            if not tools.check_internet_connectivity():
4016                gui_utils.no_internet_dialog()
4017                self._view.ui.txt_new_choose_reference.setEnabled(False)
4018                self._view.ui.lbl_new_status_choose_reference.setText("You cannot enter a PDB ID (no internet).")
4019                return
4020            self._view.ui.txt_new_choose_reference.setEnabled(True)
4021            self._view.ui.lbl_new_status_choose_reference.setText("")
4022        else:
4023            self._view.ui.lbl_new_choose_reference.hide()
4024            self._view.ui.txt_new_choose_reference.hide()
4025            self._view.ui.btn_new_choose_reference.hide()
4026            self._view.ui.lbl_new_status_choose_reference.setText("")
4027            self._view.ui.btn_new_create_project.setEnabled(True)
4028
4029    def load_reference_in_project(self) -> None:
4030        """Loads a reference in a new project."""
4031        try:
4032            # open file dialog
4033            file_name = QtWidgets.QFileDialog.getOpenFileName(
4034                self._view,
4035                "Open Reference",
4036                QtCore.QDir.homePath(),
4037                "PDB Files (*.pdb)",
4038            )
4039            if file_name == ("", ""):
4040                raise ValueError
4041            # display path in text box
4042            self._view.ui.txt_new_choose_reference.setText(str(file_name[0]))
4043            self._view.ui.txt_new_choose_reference.setEnabled(False)
4044            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4045            self._view.ui.btn_new_create_project.setEnabled(True)
4046        except ValueError:
4047            print("No file has been selected.")
4048
4049    def validate_reference_in_project(self) -> None:
4050        """Checks if the entered reference protein is valid or not."""
4051        if len(self._view.ui.txt_new_choose_reference.text()) == 0:
4052            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4053            self._view.ui.lbl_new_status_choose_reference.setText("")
4054            self._view.ui.btn_new_create_project.setEnabled(False)
4055            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4056        elif len(self._view.ui.txt_new_choose_reference.text()) < 4:
4057            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4058            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4059            self._view.ui.btn_new_create_project.setEnabled(False)
4060            self._view.ui.lbl_new_status_choose_reference.setText("")
4061        # checks if a pdb id was entered
4062        elif len(self._view.ui.txt_new_choose_reference.text()) == 4:
4063            pdb_id = self._view.ui.txt_new_choose_reference.text().upper()
4064            try:
4065                # the pdb file gets saved in a scratch directory where it gets deleted immediately
4066                cmd.fetch(pdb_id, type="pdb", path=constants.SCRATCH_DIR)
4067                os.remove(f"{constants.SCRATCH_DIR}/{pdb_id}.pdb")
4068                cmd.reinitialize()
4069                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4070                self._view.ui.btn_new_create_project.setEnabled(True)
4071            # if the id does not exist an exception gets raised
4072            except pymol.CmdException:
4073                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4074                return
4075            except FileNotFoundError:
4076                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4077                self._view.ui.lbl_new_status_choose_reference.setText("Invalid PDB ID.")
4078                self._view.ui.btn_new_create_project.setEnabled(False)
4079                return
4080        else:
4081            if self._view.ui.txt_new_choose_reference.text().find("/") == -1:
4082                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4083                self._view.ui.btn_new_create_project.setEnabled(False)
4084                styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4085
4086            elif self._view.ui.txt_new_choose_reference.text().find("\\") == -1:
4087                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4088                self._view.ui.btn_new_create_project.setEnabled(False)
4089                styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4090
4091    def validate_project_name(self) -> None:
4092        """Validates the input of the project name in real-time."""
4093        input_validator.InputValidator.validate_project_name(
4094            self._view.ui.list_new_projects,
4095            self._view.ui.txt_new_project_name,
4096            self._view.ui.lbl_new_status_project_name,
4097            self._view.ui.btn_new_create_project,
4098            self._view.ui.cb_new_add_reference,
4099        )
4100
4101    # </editor-fold>
4102
4103    # <editor-fold desc="Open project">
4104    def validate_open_search(self) -> None:
4105        """Validates the input of the project name in real-time."""
4106        if self._view.ui.list_open_projects.currentItem() is not None:
4107            self._view.ui.list_open_projects.currentItem().setSelected(False)
4108        # set color for lineEdit
4109        input_validator.InputValidator.validate_search_input(
4110            self._view.ui.list_open_projects,
4111            self._view.ui.txt_open_search,
4112            self._view.ui.lbl_open_status_search,
4113            self._view.ui.txt_open_selected_project,
4114        )
4115
4116    def select_project_from_open_list(self) -> None:
4117        """Sets the selected project name in the text box."""
4118        try:
4119            self._view.ui.txt_open_selected_project.setText(self._view.ui.list_open_projects.currentItem().text())
4120        except AttributeError:
4121            self._view.ui.txt_open_selected_project.setText("")
4122
4123    def activate_open_button(self) -> None:
4124        """Activates the open button."""
4125        if self._view.ui.txt_open_selected_project.text() == "":
4126            self._view.ui.btn_open_open_project.setEnabled(False)
4127        else:
4128            self._view.ui.btn_open_open_project.setEnabled(True)
4129
4130    # </editor-fold>
4131
4132    # <editor-fold desc="Delete project">
4133    def select_project_from_delete_list(self) -> None:
4134        """Selects a project from the project list on the delete page."""
4135        try:
4136            self._view.ui.txt_delete_selected_projects.setText(self._view.ui.list_delete_projects.currentItem().text())
4137        except AttributeError:
4138            self._view.ui.txt_delete_selected_projects.setText("")
4139
4140    def activate_delete_button(self) -> None:
4141        """Activates the delete button."""
4142        if self._view.ui.txt_delete_selected_projects.text() == "":
4143            self._view.ui.btn_delete_delete_project.setEnabled(False)
4144        else:
4145            self._view.ui.btn_delete_delete_project.setEnabled(True)
4146
4147    def validate_delete_search(self) -> None:
4148        """Validates the input of the project name in real-time."""
4149        if self._view.ui.list_delete_projects.currentItem() is not None:
4150            self._view.ui.list_delete_projects.currentItem().setSelected(False)
4151        # set color for lineEdit
4152        input_validator.InputValidator.validate_search_input(
4153            self._view.ui.list_delete_projects,
4154            self._view.ui.txt_delete_search,
4155            self._view.ui.lbl_delete_status_search,
4156            self._view.ui.txt_delete_selected_projects,
4157        )
4158
4159    # </editor-fold>
4160
4161    # <editor-fold desc="View page">
4162    def display_view_page(self) -> None:
4163        """Displays the edit project page."""
4164        if self.is_distance_plot_open:
4165            self.distance_plot_dialog.close()
4166            self.is_distance_plot_open = False
4167        self._view.ui.list_view_project_proteins.clear()
4168        self._view.ui.txtedit_view_sequence.clear()
4169        # pre-process
4170        self._view.status_bar.showMessage(self._workspace_label.text())
4171        # list all proteins from pdb directory
4172        gui_utils.fill_list_view_with_protein_names(self._current_project, self._view.ui.list_view_project_proteins)
4173
4174        tools.switch_page(
4175            self._view.ui.stackedWidget,
4176            self._view.ui.lbl_page_title,
4177            11,
4178            "View proteins of current project",
4179        )
4180        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_view_page)
4181        gui_elements_to_hide = [
4182            self._view.ui.btn_view_project_show,
4183            self._view.ui.btn_view_project_show_structure,
4184            self._view.ui.txtedit_view_sequence,
4185            self._view.ui.label_9,
4186            self._view.ui.label_11,
4187        ]
4188        gui_utils.hide_gui_elements(gui_elements_to_hide)
4189
4190    def view_show_options(self) -> None:
4191        """Controls which gui elements get shown."""
4192        gui_elements_to_show = [
4193            # self._view.ui.btn_view_project_show,
4194            self._view.ui.btn_view_project_show_structure,
4195            self._view.ui.txtedit_view_sequence,
4196            # self._view.ui.label_9,
4197            self._view.ui.label_11,
4198        ]
4199        gui_utils.show_gui_elements(gui_elements_to_show)
4200        self.view_sequence()
4201
4202    def view_sequence(self) -> None:
4203        """Displays the sequence of the selected protein in a text box."""
4204        tmp_protein_basename = self._view.ui.list_view_project_proteins.currentItem().text()
4205        tmp_protein_sequences = self._current_project.search_protein(tmp_protein_basename).get_protein_sequences()
4206        self._view.ui.txtedit_view_sequence.clear()
4207        for tmp_sequence in tmp_protein_sequences:
4208            self._view.ui.txtedit_view_sequence.append("".join(tmp_sequence.sequence))
4209        # fixme: experimental sequence viewer gui
4210        # dialog = dialog_sequence_viewer.SequenceViewer(tmp_protein_sequences, tmp_protein_filename)
4211        # dialog.exec_()
4212
4213    # </editor-fold>
4214
4215    # <editor-fold desc="Use page">
4216    def validate_use_project_name(self) -> None:
4217        """Validates the input of the project name in real-time."""
4218        input_validator.InputValidator.validate_project_name(
4219            self._view.ui.list_use_existing_projects,
4220            self._view.ui.txt_use_project_name,
4221            self._view.ui.lbl_use_status_project_name,
4222            self._view.ui.btn_use_next,
4223        )
4224
4225    def validate_use_search(self) -> None:
4226        """Validates the input of the protein name in real-time."""
4227        message = "Protein structure does not exists."
4228        input_validator.InputValidator.validate_search_input(
4229            self._view.ui.list_use_available_protein_structures,
4230            self._view.ui.txt_use_search,
4231            self._view.ui.lbl_use_status_search,
4232            status_message=message,
4233        )
4234
4235    def add_protein_structure_to_new_project(self) -> None:
4236        """Adds the selected protein to the list which is used to create the new project."""
4237        prot_to_add = self._view.ui.list_use_available_protein_structures.currentItem().text()
4238        self._view.ui.list_use_selected_protein_structures.addItem(prot_to_add)
4239        self._view.ui.list_use_available_protein_structures.takeItem(
4240            self._view.ui.list_use_available_protein_structures.currentRow(),
4241        )
4242        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4243        if self._view.ui.list_use_available_protein_structures.count() > 0:
4244            try:
4245                self._view.ui.list_use_available_protein_structures.currentItem().setSelected(False)
4246            except AttributeError:
4247                constants.PYSSA_LOGGER.debug("No selection in use available proteins list on Use page.")
4248
4249    def remove_protein_structure_to_new_project(self) -> None:
4250        """Removes the selected protein from the list which is used to create the new project."""
4251        prot_to_remove = self._view.ui.list_use_selected_protein_structures.currentItem()
4252        self._view.ui.list_use_selected_protein_structures.takeItem(
4253            self._view.ui.list_use_selected_protein_structures.currentRow(),
4254        )
4255        self._view.ui.list_use_available_protein_structures.addItem(prot_to_remove)
4256        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)
4257        if self._view.ui.list_use_selected_protein_structures.count() > 0:
4258            try:
4259                self._view.ui.list_use_selected_protein_structures.currentItem().setSelected(False)
4260            except AttributeError:
4261                constants.PYSSA_LOGGER.debug("No selection in use selected proteins list on Use page.")
4262
4263    def show_protein_selection_for_use(self) -> None:
4264        """Shows the two lists for the protein selection."""
4265        gui_elements_to_show = [
4266            self._view.ui.lbl_use_search,
4267            self._view.ui.lbl_use_status_search,
4268            self._view.ui.txt_use_search,
4269            self._view.ui.btn_use_add_available_protein_structures,
4270            self._view.ui.lbl_use_available_protein_structures,
4271            self._view.ui.list_use_available_protein_structures,
4272            self._view.ui.btn_use_remove_selected_protein_structures,
4273            self._view.ui.lbl_use_selected_protein_structures,
4274            self._view.ui.list_use_selected_protein_structures,
4275            self._view.ui.btn_use_back,
4276            self._view.ui.btn_use_create_new_project,
4277            self._view.ui.lbl_use_new_project,
4278        ]
4279        gui_utils.show_gui_elements(gui_elements_to_show)
4280        self._view.ui.txt_use_project_name.setEnabled(False)
4281        gui_elements_to_hide = [
4282            self._view.ui.btn_use_next,
4283            self._view.ui.list_use_existing_projects,
4284        ]
4285        gui_utils.hide_gui_elements(gui_elements_to_hide)
4286        gui_utils.disable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)
4287        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4288        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)
4289
4290    def hide_protein_selection_for_use(self) -> None:
4291        """Hides the two lists for the protein selection."""
4292        gui_elements_to_show = [
4293            self._view.ui.btn_use_next,
4294            self._view.ui.list_use_existing_projects,
4295        ]
4296        gui_utils.show_gui_elements(gui_elements_to_show)
4297        self._view.ui.txt_use_project_name.setEnabled(True)
4298
4299        gui_elements_to_hide = [
4300            self._view.ui.lbl_use_search,
4301            self._view.ui.lbl_use_status_search,
4302            self._view.ui.txt_use_search,
4303            self._view.ui.btn_use_add_available_protein_structures,
4304            self._view.ui.lbl_use_available_protein_structures,
4305            self._view.ui.list_use_available_protein_structures,
4306            self._view.ui.btn_use_remove_selected_protein_structures,
4307            self._view.ui.lbl_use_selected_protein_structures,
4308            self._view.ui.list_use_selected_protein_structures,
4309            self._view.ui.btn_use_back,
4310            self._view.ui.btn_use_create_new_project,
4311            self._view.ui.lbl_use_new_project,
4312        ]
4313        gui_utils.hide_gui_elements(gui_elements_to_hide)
4314        gui_utils.enable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)
4315
4316    def use_enable_add(self) -> None:
4317        """Enables the add button."""
4318        self._view.ui.btn_use_add_available_protein_structures.setEnabled(True)
4319
4320    def use_enable_remove(self) -> None:
4321        """Enables the remove button."""
4322        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(True)
4323
4324    # </editor-fold>
4325
4326    # <editor-fold desc="ESM fold">
4327    def _init_esm_pred_mono_page(self) -> None:
4328        """Clears all text boxes and sets up the default values for the page."""
4329        # clears everything
4330        self._view.ui.txt_esm_prot_name.clear()
4331        self._view.ui.txt_esm_prot_seq.clear()
4332        for i in range(self._view.ui.table_esm_prot_to_predict.rowCount()):
4333            self._view.ui.table_esm_prot_to_predict.removeRow(i)
4334        # sets up defaults: Prediction
4335        self._view.ui.btn_esm_next.setEnabled(False)
4336        self._view.ui.btn_esm_next_2.setEnabled(False)
4337        self._view.ui.lbl_esm_prot_name_status.setText("")
4338        self._view.ui.lbl_esm_prot_seq_status.setText("")
4339
4340    def display_esm_pred_mono(self) -> None:
4341        """Displays the esm_fold monomer page."""
4342        self._init_esm_pred_mono_page()
4343        gui_elements_to_show = [
4344            self._view.ui.lbl_esm_prot_to_predict,
4345            self._view.ui.table_esm_prot_to_predict,
4346            self._view.ui.btn_esm_seq_to_predict,
4347        ]
4348        gui_elements_to_hide = [
4349            self._view.ui.btn_esm_seq_to_predict_remove,
4350            self._view.ui.lbl_esm_prot_name,
4351            self._view.ui.txt_esm_prot_name,
4352            self._view.ui.lbl_esm_prot_name_status,
4353            self._view.ui.btn_esm_back,
4354            self._view.ui.btn_esm_next,
4355            self._view.ui.lbl_esm_prot_seq,
4356            self._view.ui.txt_esm_prot_seq,
4357            self._view.ui.lbl_esm_prot_seq_status,
4358            self._view.ui.btn_esm_back_2,
4359            self._view.ui.btn_esm_next_2,
4360            self._view.ui.btn_esm_predict,
4361        ]
4362        gui_utils.show_gui_elements(gui_elements_to_show)
4363        gui_utils.hide_gui_elements(gui_elements_to_hide)
4364        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4365        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 1, "ESMFold Monomer Prediction")
4366        self.last_sidebar_button = styles.color_sidebar_buttons(
4367            self.last_sidebar_button,
4368            self._view.ui.btn_pred_cloud_monomer_page,
4369        )
4370
4371    def cloud_esm_validate_protein_name(self) -> None:
4372        """Validates the input of the protein name in real-time."""
4373        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4374            self._view.ui.txt_esm_prot_name.text(),
4375            self._view.ui.table_esm_prot_to_predict,
4376        ):
4377            self._view.ui.lbl_esm_prot_name_status.setText("Protein name already used.")
4378            self._view.ui.btn_esm_next.setEnabled(False)
4379            styles.color_button_not_ready(self._view.ui.btn_esm_next)
4380        else:
4381            self._view.ui.btn_esm_next.setEnabled(True)
4382            tools.validate_protein_name(
4383                self._view.ui.txt_esm_prot_name,
4384                self._view.ui.lbl_esm_prot_name_status,
4385                self._view.ui.btn_esm_next,
4386            )
4387
4388    def cloud_esm_validate_protein_sequence(self) -> None:
4389        """Validates the input of the protein sequence in real-time."""
4390        tools.validate_protein_sequence(
4391            self._view.ui.txt_esm_prot_seq,
4392            self._view.ui.lbl_esm_prot_seq_status,
4393            self._view.ui.btn_esm_next_2,
4394        )
4395
4396    def setup_defaults_esm_monomer_prediction(self) -> None:
4397        """Sets up the default values for the page."""
4398        # clears everything
4399        self._view.ui.txt_esm_prot_name.clear()
4400        self._view.ui.txt_esm_prot_seq.clear()
4401        # sets up defaults: Prediction
4402        self._view.ui.btn_esm_next.setEnabled(False)
4403        self._view.ui.btn_esm_next_2.setEnabled(False)
4404        self._view.ui.lbl_esm_prot_name_status.setText("")
4405        self._view.ui.lbl_esm_prot_seq_status.setText("")
4406
4407    def cloud_esm_add_seq_to_predict(self) -> None:
4408        """Shows the gui elements to add a sequence to the protein to predict."""
4409        gui_elements_to_show = [
4410            self._view.ui.lbl_esm_prot_to_predict,
4411            self._view.ui.table_esm_prot_to_predict,
4412            self._view.ui.lbl_esm_prot_name,
4413            self._view.ui.txt_esm_prot_name,
4414            self._view.ui.lbl_esm_prot_name_status,
4415            self._view.ui.btn_esm_back,
4416            self._view.ui.btn_esm_next,
4417        ]
4418        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4419        gui_elements_to_hide = [
4420            self._view.ui.btn_esm_seq_to_predict_remove,
4421            self._view.ui.btn_esm_seq_to_predict,
4422            self._view.ui.lbl_esm_prot_seq,
4423            self._view.ui.txt_esm_prot_seq,
4424            self._view.ui.lbl_esm_prot_seq_status,
4425            self._view.ui.btn_esm_back_2,
4426            self._view.ui.btn_esm_next_2,
4427            self._view.ui.btn_esm_predict,
4428        ]
4429        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4430        gui_utils.show_gui_elements(gui_elements_to_show)
4431        gui_utils.hide_gui_elements(gui_elements_to_hide)
4432        self._view.ui.btn_esm_next.setEnabled(False)
4433        self._view.ui.txt_esm_prot_name.clear()
4434        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4435        if self._view.ui.table_esm_prot_to_predict.rowCount() > 0:
4436            try:
4437                self._view.ui.table_esm_prot_to_predict.currentItem().setSelected(False)
4438            except AttributeError:
4439                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
4440
4441    def cloud_esm_back(self) -> None:
4442        """Hides the gui elements for the protein name."""
4443        gui_elements_to_show = [
4444            self._view.ui.lbl_esm_prot_to_predict,
4445            self._view.ui.table_esm_prot_to_predict,
4446            self._view.ui.btn_esm_seq_to_predict_remove,
4447            self._view.ui.btn_esm_seq_to_predict,
4448        ]
4449        gui_elements_to_hide = [
4450            self._view.ui.lbl_esm_prot_name,
4451            self._view.ui.txt_esm_prot_name,
4452            self._view.ui.lbl_esm_prot_name_status,
4453            self._view.ui.btn_esm_back,
4454            self._view.ui.btn_esm_next,
4455            self._view.ui.lbl_esm_prot_seq,
4456            self._view.ui.txt_esm_prot_seq,
4457            self._view.ui.lbl_esm_prot_seq_status,
4458            self._view.ui.btn_esm_back_2,
4459            self._view.ui.btn_esm_next_2,
4460            self._view.ui.btn_esm_predict,
4461        ]
4462        gui_utils.show_gui_elements(gui_elements_to_show)
4463        gui_utils.hide_gui_elements(gui_elements_to_hide)
4464        self.cloud_esm_check_if_table_is_empty()
4465        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4466
4467    def cloud_esm_next(self) -> None:
4468        """Shows the gui elements for the protein name."""
4469        gui_elements_to_show = [
4470            self._view.ui.lbl_esm_prot_to_predict,
4471            self._view.ui.table_esm_prot_to_predict,
4472            self._view.ui.lbl_esm_prot_name,
4473            self._view.ui.txt_esm_prot_name,
4474            self._view.ui.lbl_esm_prot_seq,
4475            self._view.ui.txt_esm_prot_seq,
4476            self._view.ui.lbl_esm_prot_seq_status,
4477            self._view.ui.btn_esm_back_2,
4478            self._view.ui.btn_esm_next_2,
4479        ]
4480        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4481        gui_elements_to_hide = [
4482            self._view.ui.btn_esm_seq_to_predict_remove,
4483            self._view.ui.btn_esm_seq_to_predict,
4484            self._view.ui.lbl_esm_prot_name_status,
4485            self._view.ui.btn_esm_back,
4486            self._view.ui.btn_esm_next,
4487            self._view.ui.btn_esm_predict,
4488        ]
4489        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4490        gui_utils.show_gui_elements(gui_elements_to_show)
4491        gui_utils.hide_gui_elements(gui_elements_to_hide)
4492        self._view.ui.txt_esm_prot_seq.clear()
4493
4494    def cloud_esm_back_2(self) -> None:
4495        """Hides the gui elements for the protein sequence."""
4496        gui_elements_to_show = [
4497            self._view.ui.lbl_esm_prot_to_predict,
4498            self._view.ui.table_esm_prot_to_predict,
4499            self._view.ui.lbl_esm_prot_name,
4500            self._view.ui.txt_esm_prot_name,
4501            self._view.ui.lbl_esm_prot_name_status,
4502            self._view.ui.btn_esm_back,
4503            self._view.ui.btn_esm_next,
4504        ]
4505        gui_elements_to_hide = [
4506            self._view.ui.btn_esm_seq_to_predict_remove,
4507            self._view.ui.btn_esm_seq_to_predict,
4508            self._view.ui.lbl_esm_prot_seq,
4509            self._view.ui.txt_esm_prot_seq,
4510            self._view.ui.lbl_esm_prot_seq_status,
4511            self._view.ui.btn_esm_back_2,
4512            self._view.ui.btn_esm_next_2,
4513            self._view.ui.btn_esm_predict,
4514        ]
4515        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4516        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4517        gui_utils.show_gui_elements(gui_elements_to_show)
4518        gui_utils.hide_gui_elements(gui_elements_to_hide)
4519
4520    def cloud_esm_add_protein(self) -> None:
4521        """Adds protein to the list of proteins to predict."""
4522        self._view.ui.table_esm_prot_to_predict.setRowCount(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4523        self._view.ui.table_esm_prot_to_predict.insertRow(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4524        self._view.ui.table_esm_prot_to_predict.setItem(
4525            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4526            0,
4527            QtWidgets.QTableWidgetItem("A"),
4528        )
4529        self._view.ui.table_esm_prot_to_predict.setItem(
4530            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4531            1,
4532            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_seq.toPlainText()),
4533        )
4534        self._view.ui.table_esm_prot_to_predict.setVerticalHeaderItem(
4535            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4536            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_name.text()),
4537        )
4538        self._view.ui.table_esm_prot_to_predict.resizeColumnsToContents()
4539        self.cloud_esm_check_if_table_is_empty()
4540        gui_elements_to_show = [
4541            self._view.ui.lbl_esm_prot_to_predict,
4542            self._view.ui.table_esm_prot_to_predict,
4543            self._view.ui.btn_esm_seq_to_predict_remove,
4544            self._view.ui.btn_esm_seq_to_predict,
4545            self._view.ui.btn_esm_predict,
4546        ]
4547        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4548        gui_elements_to_hide = [
4549            self._view.ui.lbl_esm_prot_name,
4550            self._view.ui.txt_esm_prot_name,
4551            self._view.ui.lbl_esm_prot_name_status,
4552            self._view.ui.btn_esm_back,
4553            self._view.ui.btn_esm_next,
4554            self._view.ui.lbl_esm_prot_seq,
4555            self._view.ui.txt_esm_prot_seq,
4556            self._view.ui.lbl_esm_prot_seq_status,
4557            self._view.ui.btn_esm_back_2,
4558            self._view.ui.btn_esm_next_2,
4559        ]
4560        gui_utils.show_gui_elements(gui_elements_to_show)
4561        gui_utils.hide_gui_elements(gui_elements_to_hide)
4562        self._view.ui.btn_esm_predict.setEnabled(True)
4563        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4564        self.setup_defaults_esm_monomer_prediction()
4565
4566    def cloud_esm_remove(self) -> None:
4567        """Removes a protein from the list of proteins to predict."""
4568        self._view.ui.table_esm_prot_to_predict.removeRow(self._view.ui.table_esm_prot_to_predict.currentRow())
4569        gui_elements_to_show = [
4570            self._view.ui.lbl_esm_prot_to_predict,
4571            self._view.ui.table_esm_prot_to_predict,
4572            self._view.ui.btn_esm_seq_to_predict_remove,
4573            self._view.ui.btn_esm_seq_to_predict,
4574            self._view.ui.btn_esm_predict,
4575        ]
4576        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4577        gui_elements_to_hide = [
4578            self._view.ui.lbl_esm_prot_name,
4579            self._view.ui.txt_esm_prot_name,
4580            self._view.ui.lbl_esm_prot_name_status,
4581            self._view.ui.btn_esm_back,
4582            self._view.ui.btn_esm_next,
4583            self._view.ui.lbl_esm_prot_seq,
4584            self._view.ui.txt_esm_prot_seq,
4585            self._view.ui.lbl_esm_prot_seq_status,
4586            self._view.ui.btn_esm_back_2,
4587            self._view.ui.btn_esm_next_2,
4588        ]
4589        gui_utils.show_gui_elements(gui_elements_to_show)
4590        gui_utils.hide_gui_elements(gui_elements_to_hide)
4591        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4592        self.cloud_esm_check_if_table_is_empty()
4593
4594    def cloud_esm_item_changed(self) -> None:
4595        """Enables the remove button."""
4596        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(True)
4597
4598    def cloud_esm_check_if_table_is_empty(self) -> None:
4599        """Checks if the table proteins to predict is empty."""
4600        if self._view.ui.table_esm_prot_to_predict.rowCount() == 0:
4601            styles.color_button_not_ready(self._view.ui.btn_esm_predict)
4602            self._view.ui.btn_esm_predict.setEnabled(False)
4603            gui_elements_to_show = [
4604                self._view.ui.lbl_esm_prot_to_predict,
4605                self._view.ui.table_esm_prot_to_predict,
4606                self._view.ui.btn_esm_seq_to_predict,
4607            ]
4608            gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4609            gui_elements_to_hide = [
4610                self._view.ui.btn_esm_seq_to_predict_remove,
4611                self._view.ui.lbl_esm_prot_name,
4612                self._view.ui.txt_esm_prot_name,
4613                self._view.ui.lbl_esm_prot_name_status,
4614                self._view.ui.btn_esm_back,
4615                self._view.ui.btn_esm_next,
4616                self._view.ui.lbl_esm_prot_seq,
4617                self._view.ui.txt_esm_prot_seq,
4618                self._view.ui.lbl_esm_prot_seq_status,
4619                self._view.ui.btn_esm_back_2,
4620                self._view.ui.btn_esm_next_2,
4621                self._view.ui.btn_esm_predict,
4622            ]
4623            gui_utils.show_gui_elements(gui_elements_to_show)
4624            gui_utils.hide_gui_elements(gui_elements_to_hide)
4625        else:
4626            self._view.ui.btn_esm_predict.setEnabled(True)
4627
4628    # </editor-fold>
4629
4630    # <editor-fold desc="Monomer local prediction">
4631    def _init_local_pred_mono_page(self) -> None:
4632        """Clears all text boxes and sets default values for the gui elements."""
4633        # clears everything
4634        self._view.ui.txt_pred_mono_prot_name.clear()
4635        self._view.ui.txt_pred_mono_seq_name.clear()
4636        for i in range(self._view.ui.table_pred_mono_prot_to_predict.rowCount()):
4637            self._view.ui.table_pred_mono_prot_to_predict.removeRow(i)
4638        # sets up defaults: Prediction
4639        self._view.ui.btn_pred_mono_next.setEnabled(False)
4640        self._view.ui.btn_pred_mono_add_protein.setEnabled(False)
4641        self._view.ui.lbl_pred_mono_prot_name_status.setText("")
4642        self._view.ui.lbl_pred_mono_seq_name_status.setText("")
4643
4644    def display_local_pred_mono(self) -> None:
4645        """Displays the local prediction monomer page."""
4646        # checks internet connection
4647        if not tools.check_internet_connectivity():
4648            gui_utils.no_internet_dialog()
4649            return
4650        self._init_local_pred_mono_page()
4651        gui_elements_to_show = [
4652            self._view.ui.lbl_pred_mono_prot_to_predict,
4653            self._view.ui.table_pred_mono_prot_to_predict,
4654            self._view.ui.btn_pred_mono_seq_to_predict,
4655        ]
4656        gui_elements_to_hide = [
4657            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4658            self._view.ui.lbl_pred_mono_prot_name,
4659            self._view.ui.txt_pred_mono_prot_name,
4660            self._view.ui.lbl_pred_mono_prot_name_status,
4661            self._view.ui.btn_pred_mono_back,
4662            self._view.ui.btn_pred_mono_next,
4663            self._view.ui.lbl_pred_mono_seq_name,
4664            self._view.ui.txt_pred_mono_seq_name,
4665            self._view.ui.lbl_pred_mono_seq_name_status,
4666            self._view.ui.btn_pred_mono_back_2,
4667            self._view.ui.btn_pred_mono_add_protein,
4668            self._view.ui.lbl_pred_mono_advanced_config,
4669            self._view.ui.btn_pred_mono_advanced_config,
4670            self._view.ui.btn_pred_mono_predict,
4671        ]
4672        gui_utils.show_gui_elements(gui_elements_to_show)
4673        gui_utils.hide_gui_elements(gui_elements_to_hide)
4674        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4675        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 19, "Local Monomer Prediction")
4676        self.last_sidebar_button = styles.color_sidebar_buttons(
4677            self.last_sidebar_button,
4678            self._view.ui.btn_pred_local_monomer_page,
4679        )
4680
4681    def local_pred_mono_validate_protein_name(self) -> None:
4682        """Validates the input of the protein name in real-time."""
4683        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4684            self._view.ui.txt_pred_mono_prot_name.text(),
4685            self._view.ui.table_pred_mono_prot_to_predict,
4686        ):
4687            self._view.ui.lbl_pred_mono_prot_name_status.setText("Protein name already used.")
4688            self._view.ui.btn_pred_mono_next.setEnabled(False)
4689            styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4690        else:
4691            self._view.ui.btn_pred_mono_next.setEnabled(True)
4692            tools.validate_protein_name(
4693                self._view.ui.txt_pred_mono_prot_name,
4694                self._view.ui.lbl_pred_mono_prot_name_status,
4695                self._view.ui.btn_pred_mono_next,
4696            )
4697
4698    def local_pred_mono_validate_protein_sequence(self) -> None:
4699        """Validates the input of the protein sequence in real-time."""
4700        tools.validate_protein_sequence(
4701            self._view.ui.txt_pred_mono_seq_name,
4702            self._view.ui.lbl_pred_mono_seq_name_status,
4703            self._view.ui.btn_pred_mono_add_protein,
4704        )
4705
4706    def show_prediction_configuration(self) -> None:
4707        """Opens the prediction configuration dialog window."""
4708        config = dialog_advanced_prediction_configurations.DialogAdvancedPredictionConfigurations(
4709            self.prediction_configuration,
4710        )
4711        config.exec_()
4712        self.prediction_configuration.amber_force_field = config.prediction_config.amber_force_field
4713        self.prediction_configuration.templates = config.prediction_config.templates
4714
4715    def setup_defaults_monomer_prediction(self) -> None:
4716        """Sets up the defaults for the page."""
4717        # clears everything
4718        self._view.ui.txt_pred_mono_prot_name.clear()
4719        self._view.ui.txt_pred_mono_seq_name.clear()
4720        # sets up defaults: Prediction
4721        self._view.ui.btn_pred_mono_next.setEnabled(False)
4722        self._view.ui.btn_pred_mono_add_protein.setEnabled(False)
4723        self._view.ui.lbl_pred_mono_prot_name_status.setText("")
4724        self._view.ui.lbl_pred_mono_seq_name_status.setText("")
4725
4726    def local_pred_mono_add_seq_to_predict(self) -> None:
4727        """Shows the gui elements for the protein name."""
4728        gui_elements_to_show = [
4729            self._view.ui.lbl_pred_mono_prot_to_predict,
4730            self._view.ui.table_pred_mono_prot_to_predict,
4731            self._view.ui.lbl_pred_mono_prot_name,
4732            self._view.ui.txt_pred_mono_prot_name,
4733            self._view.ui.lbl_pred_mono_prot_name_status,
4734            self._view.ui.btn_pred_mono_back,
4735            self._view.ui.btn_pred_mono_next,
4736        ]
4737        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4738        gui_elements_to_hide = [
4739            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4740            self._view.ui.btn_pred_mono_seq_to_predict,
4741            self._view.ui.lbl_pred_mono_seq_name,
4742            self._view.ui.txt_pred_mono_seq_name,
4743            self._view.ui.lbl_pred_mono_seq_name_status,
4744            self._view.ui.btn_pred_mono_back_2,
4745            self._view.ui.btn_pred_mono_add_protein,
4746            self._view.ui.lbl_pred_mono_advanced_config,
4747            self._view.ui.btn_pred_mono_advanced_config,
4748            self._view.ui.btn_pred_mono_predict,
4749        ]
4750        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4751        gui_utils.show_gui_elements(gui_elements_to_show)
4752        gui_utils.hide_gui_elements(gui_elements_to_hide)
4753        self._view.ui.btn_pred_mono_next.setEnabled(False)
4754        self._view.ui.txt_pred_mono_prot_name.clear()
4755        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4756        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() > 0:
4757            try:
4758                self._view.ui.table_pred_mono_prot_to_predict.currentItem().setSelected(False)
4759            except AttributeError:
4760                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
4761
4762    def local_pred_mono_back(self) -> None:
4763        """Hides the gui elements for the protein name."""
4764        gui_elements_to_show = [
4765            self._view.ui.lbl_pred_mono_prot_to_predict,
4766            self._view.ui.table_pred_mono_prot_to_predict,
4767            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4768            self._view.ui.btn_pred_mono_seq_to_predict,
4769        ]
4770        gui_elements_to_hide = [
4771            self._view.ui.lbl_pred_mono_prot_name,
4772            self._view.ui.txt_pred_mono_prot_name,
4773            self._view.ui.lbl_pred_mono_prot_name_status,
4774            self._view.ui.btn_pred_mono_back,
4775            self._view.ui.btn_pred_mono_next,
4776            self._view.ui.lbl_pred_mono_seq_name,
4777            self._view.ui.txt_pred_mono_seq_name,
4778            self._view.ui.lbl_pred_mono_seq_name_status,
4779            self._view.ui.btn_pred_mono_back_2,
4780            self._view.ui.btn_pred_mono_add_protein,
4781            self._view.ui.lbl_pred_mono_advanced_config,
4782            self._view.ui.btn_pred_mono_advanced_config,
4783            self._view.ui.btn_pred_mono_predict,
4784        ]
4785        gui_utils.show_gui_elements(gui_elements_to_show)
4786        gui_utils.hide_gui_elements(gui_elements_to_hide)
4787        self.local_pred_mono_check_if_table_is_empty()
4788        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4789
4790    def local_pred_mono_next(self) -> None:
4791        """Shows the gui elements for the protein sequence."""
4792        gui_elements_to_show = [
4793            self._view.ui.lbl_pred_mono_prot_to_predict,
4794            self._view.ui.table_pred_mono_prot_to_predict,
4795            self._view.ui.lbl_pred_mono_prot_name,
4796            self._view.ui.txt_pred_mono_prot_name,
4797            self._view.ui.lbl_pred_mono_seq_name,
4798            self._view.ui.txt_pred_mono_seq_name,
4799            self._view.ui.lbl_pred_mono_seq_name_status,
4800            self._view.ui.btn_pred_mono_back_2,
4801            self._view.ui.btn_pred_mono_add_protein,
4802        ]
4803        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4804        gui_elements_to_hide = [
4805            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4806            self._view.ui.btn_pred_mono_seq_to_predict,
4807            self._view.ui.lbl_pred_mono_prot_name_status,
4808            self._view.ui.btn_pred_mono_back,
4809            self._view.ui.btn_pred_mono_next,
4810            self._view.ui.lbl_pred_mono_advanced_config,
4811            self._view.ui.btn_pred_mono_advanced_config,
4812            self._view.ui.btn_pred_mono_predict,
4813        ]
4814        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4815        gui_utils.show_gui_elements(gui_elements_to_show)
4816        gui_utils.hide_gui_elements(gui_elements_to_hide)
4817        self._view.ui.txt_pred_mono_seq_name.clear()
4818
4819    def local_pred_mono_back_2(self) -> None:
4820        """Hides the gui elements for the protein sequence."""
4821        gui_elements_to_show = [
4822            self._view.ui.lbl_pred_mono_prot_to_predict,
4823            self._view.ui.table_pred_mono_prot_to_predict,
4824            self._view.ui.lbl_pred_mono_prot_name,
4825            self._view.ui.txt_pred_mono_prot_name,
4826            self._view.ui.lbl_pred_mono_prot_name_status,
4827            self._view.ui.btn_pred_mono_back,
4828            self._view.ui.btn_pred_mono_next,
4829        ]
4830        gui_elements_to_hide = [
4831            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4832            self._view.ui.btn_pred_mono_seq_to_predict,
4833            self._view.ui.lbl_pred_mono_seq_name,
4834            self._view.ui.txt_pred_mono_seq_name,
4835            self._view.ui.lbl_pred_mono_seq_name_status,
4836            self._view.ui.btn_pred_mono_back_2,
4837            self._view.ui.btn_pred_mono_add_protein,
4838            self._view.ui.lbl_pred_mono_advanced_config,
4839            self._view.ui.btn_pred_mono_advanced_config,
4840            self._view.ui.btn_pred_mono_predict,
4841        ]
4842        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4843        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4844        gui_utils.show_gui_elements(gui_elements_to_show)
4845        gui_utils.hide_gui_elements(gui_elements_to_hide)
4846
4847    def local_pred_mono_add_protein(self) -> None:
4848        """Adds protein to the list of proteins to predict."""
4849        self._view.ui.table_pred_mono_prot_to_predict.setRowCount(
4850            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4851        )
4852        self._view.ui.table_pred_mono_prot_to_predict.insertRow(
4853            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4854        )
4855        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4856            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4857            0,
4858            QtWidgets.QTableWidgetItem("A"),
4859        )
4860        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4861            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4862            1,
4863            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_seq_name.toPlainText()),
4864        )
4865        self._view.ui.table_pred_mono_prot_to_predict.setVerticalHeaderItem(
4866            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4867            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_prot_name.text()),
4868        )
4869        self._view.ui.table_pred_mono_prot_to_predict.resizeColumnsToContents()
4870        self.local_pred_mono_check_if_table_is_empty()
4871        gui_elements_to_show = [
4872            self._view.ui.lbl_pred_mono_prot_to_predict,
4873            self._view.ui.table_pred_mono_prot_to_predict,
4874            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4875            self._view.ui.btn_pred_mono_seq_to_predict,
4876            self._view.ui.lbl_pred_mono_advanced_config,
4877            self._view.ui.btn_pred_mono_advanced_config,
4878            self._view.ui.btn_pred_mono_predict,
4879        ]
4880        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4881        gui_elements_to_hide = [
4882            self._view.ui.lbl_pred_mono_prot_name,
4883            self._view.ui.txt_pred_mono_prot_name,
4884            self._view.ui.lbl_pred_mono_prot_name_status,
4885            self._view.ui.btn_pred_mono_back,
4886            self._view.ui.btn_pred_mono_next,
4887            self._view.ui.lbl_pred_mono_seq_name,
4888            self._view.ui.txt_pred_mono_seq_name,
4889            self._view.ui.lbl_pred_mono_seq_name_status,
4890            self._view.ui.btn_pred_mono_back_2,
4891            self._view.ui.btn_pred_mono_add_protein,
4892        ]
4893        gui_utils.show_gui_elements(gui_elements_to_show)
4894        gui_utils.hide_gui_elements(gui_elements_to_hide)
4895        self._view.ui.btn_pred_mono_predict.setEnabled(True)
4896        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4897        self.setup_defaults_monomer_prediction()
4898
4899    def local_pred_mono_remove(self) -> None:
4900        """Removes the selected protein from the list of proteins to predict."""
4901        self._view.ui.table_pred_mono_prot_to_predict.removeRow(
4902            self._view.ui.table_pred_mono_prot_to_predict.currentRow(),
4903        )
4904        gui_elements_to_show = [
4905            self._view.ui.lbl_pred_mono_prot_to_predict,
4906            self._view.ui.table_pred_mono_prot_to_predict,
4907            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4908            self._view.ui.btn_pred_mono_seq_to_predict,
4909            self._view.ui.lbl_pred_mono_advanced_config,
4910            self._view.ui.btn_pred_mono_advanced_config,
4911            self._view.ui.btn_pred_mono_predict,
4912        ]
4913        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4914        gui_elements_to_hide = [
4915            self._view.ui.lbl_pred_mono_prot_name,
4916            self._view.ui.txt_pred_mono_prot_name,
4917            self._view.ui.lbl_pred_mono_prot_name_status,
4918            self._view.ui.btn_pred_mono_back,
4919            self._view.ui.btn_pred_mono_next,
4920            self._view.ui.lbl_pred_mono_seq_name,
4921            self._view.ui.txt_pred_mono_seq_name,
4922            self._view.ui.lbl_pred_mono_seq_name_status,
4923            self._view.ui.btn_pred_mono_back_2,
4924            self._view.ui.btn_pred_mono_add_protein,
4925        ]
4926        gui_utils.show_gui_elements(gui_elements_to_show)
4927        gui_utils.hide_gui_elements(gui_elements_to_hide)
4928        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4929        self.local_pred_mono_check_if_table_is_empty()
4930
4931    def local_pred_mono_item_changed(self) -> None:
4932        """Enables the remove button."""
4933        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(True)
4934
4935    def local_pred_mono_check_if_table_is_empty(self) -> None:
4936        """Checks if the table proteins to predict is empty."""
4937        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() == 0:
4938            styles.color_button_not_ready(self._view.ui.btn_pred_mono_predict)
4939            self._view.ui.btn_pred_mono_predict.setEnabled(False)
4940            gui_elements_to_show = [
4941                self._view.ui.lbl_pred_mono_prot_to_predict,
4942                self._view.ui.table_pred_mono_prot_to_predict,
4943                self._view.ui.btn_pred_mono_seq_to_predict,
4944            ]
4945            gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4946            gui_elements_to_hide = [
4947                self._view.ui.btn_pred_mono_seq_to_predict_remove,
4948                self._view.ui.lbl_pred_mono_prot_name,
4949                self._view.ui.txt_pred_mono_prot_name,
4950                self._view.ui.lbl_pred_mono_prot_name_status,
4951                self._view.ui.btn_pred_mono_back,
4952                self._view.ui.btn_pred_mono_next,
4953                self._view.ui.lbl_pred_mono_seq_name,
4954                self._view.ui.txt_pred_mono_seq_name,
4955                self._view.ui.lbl_pred_mono_seq_name_status,
4956                self._view.ui.btn_pred_mono_back_2,
4957                self._view.ui.btn_pred_mono_add_protein,
4958                self._view.ui.lbl_pred_mono_advanced_config,
4959                self._view.ui.btn_pred_mono_advanced_config,
4960                self._view.ui.btn_pred_mono_predict,
4961            ]
4962            gui_utils.show_gui_elements(gui_elements_to_show)
4963            gui_utils.hide_gui_elements(gui_elements_to_hide)
4964        else:
4965            self._view.ui.btn_pred_mono_predict.setEnabled(True)
4966
4967    # </editor-fold>
4968
4969    # <editor-fold desc="Multimer local prediction">
4970    def _init_local_pred_multi_page(self) -> None:
4971        """Clears all text boxes and sets default values for the gui elements."""
4972        # clears everything
4973        self._view.ui.txt_pred_multi_prot_name.clear()
4974        self._view.ui.txt_pred_multi_prot_seq.clear()
4975        self._view.ui.list_pred_multi_prot_seq_overview.clear()
4976        # sets up defaults: Prediction
4977        self._view.ui.btn_pred_multi_next.setEnabled(False)
4978        self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
4979        self._view.ui.lbl_pred_multi_prot_name_status.setText("")
4980        self._view.ui.lbl_pred_multi_prot_seq_status.setText("")
4981
4982    def display_local_pred_multi(self) -> None:
4983        """Displays the local prediction multimer page."""
4984        # checks internet connection
4985        if not tools.check_internet_connectivity():
4986            gui_utils.no_internet_dialog()
4987            return
4988
4989        gui_elements_to_show = [
4990            self._view.ui.lbl_pred_multi_prot_to_predict,
4991            self._view.ui.table_pred_multi_prot_to_predict,
4992            self._view.ui.btn_pred_multi_prot_to_predict_add,
4993        ]
4994        gui_elements_to_hide = [
4995            self._view.ui.btn_pred_multi_prot_to_predict_remove,
4996            self._view.ui.lbl_pred_multi_prot_name_status,
4997            self._view.ui.btn_pred_multi_back,
4998            self._view.ui.btn_pred_multi_next,
4999            self._view.ui.lbl_pred_multi_prot_name,
5000            self._view.ui.txt_pred_multi_prot_name,
5001            self._view.ui.lbl_pred_multi_prot_seq,
5002            self._view.ui.txt_pred_multi_prot_seq,
5003            self._view.ui.lbl_pred_multi_prot_seq_status,
5004            self._view.ui.lbl_pred_multi_prot_seq_add,
5005            self._view.ui.btn_pred_multi_prot_seq_add,
5006            self._view.ui.lbl_pred_multi_prot_seq_overview,
5007            self._view.ui.list_pred_multi_prot_seq_overview,
5008            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5009            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5010            self._view.ui.btn_pred_multi_back_2,
5011            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5012            self._view.ui.lbl_pred_multi_advanced_config,
5013            self._view.ui.btn_pred_multi_advanced_config,
5014            self._view.ui.btn_pred_multi_predict,
5015        ]
5016        for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1, -1, -1):
5017            self._view.ui.table_pred_multi_prot_to_predict.removeRow(i)
5018        gui_utils.show_gui_elements(gui_elements_to_show)
5019        gui_utils.hide_gui_elements(gui_elements_to_hide)
5020        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 20, "Local Multimer Prediction")
5021        self.last_sidebar_button = styles.color_sidebar_buttons(
5022            self.last_sidebar_button,
5023            self._view.ui.btn_pred_local_multimer_page,
5024        )
5025
5026    def local_pred_multi_validate_protein_name(self) -> None:
5027        """Validates the input of the protein name in real-time."""
5028        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5029            self._view.ui.txt_pred_multi_prot_name.text(),
5030            self._view.ui.table_pred_multi_prot_to_predict,
5031        ):
5032            self._view.ui.lbl_pred_multi_prot_name_status.setText("Protein name already used.")
5033            self._view.ui.btn_pred_multi_next.setEnabled(False)
5034            styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5035        else:
5036            self._view.ui.btn_pred_multi_next.setEnabled(True)
5037            tools.validate_protein_name(
5038                self._view.ui.txt_pred_multi_prot_name,
5039                self._view.ui.lbl_pred_multi_prot_name_status,
5040                self._view.ui.btn_pred_multi_next,
5041            )
5042
5043    def local_pred_multi_validate_protein_sequence(self) -> None:
5044        """Validates the input of the protein sequence in real-time."""
5045        tools.validate_protein_sequence(
5046            self._view.ui.txt_pred_multi_prot_seq,
5047            self._view.ui.lbl_pred_multi_prot_seq_status,
5048            self._view.ui.btn_pred_multi_prot_seq_add,
5049        )
5050
5051    def local_pred_multi_check_if_table_is_empty(self) -> None:
5052        """Checks if the table proteins to predict is empty."""
5053        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() == 0:
5054            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
5055            self._view.ui.btn_pred_multi_predict.setEnabled(False)
5056            gui_elements_to_show = [
5057                self._view.ui.lbl_pred_multi_prot_to_predict,
5058                self._view.ui.table_pred_multi_prot_to_predict,
5059                self._view.ui.btn_pred_multi_prot_to_predict_add,
5060            ]
5061            gui_elements_to_hide = [
5062                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5063                self._view.ui.lbl_pred_multi_prot_name_status,
5064                self._view.ui.btn_pred_multi_back,
5065                self._view.ui.btn_pred_multi_next,
5066                self._view.ui.lbl_pred_multi_prot_name,
5067                self._view.ui.txt_pred_multi_prot_name,
5068                self._view.ui.lbl_pred_multi_prot_seq,
5069                self._view.ui.txt_pred_multi_prot_seq,
5070                self._view.ui.lbl_pred_multi_prot_seq_status,
5071                self._view.ui.lbl_pred_multi_prot_seq_add,
5072                self._view.ui.btn_pred_multi_prot_seq_add,
5073                self._view.ui.lbl_pred_multi_prot_seq_overview,
5074                self._view.ui.list_pred_multi_prot_seq_overview,
5075                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5076                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5077                self._view.ui.btn_pred_multi_back_2,
5078                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5079                self._view.ui.lbl_pred_multi_advanced_config,
5080                self._view.ui.btn_pred_multi_advanced_config,
5081                self._view.ui.btn_pred_multi_predict,
5082            ]
5083            gui_utils.show_gui_elements(gui_elements_to_show)
5084            gui_utils.hide_gui_elements(gui_elements_to_hide)
5085            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5086        else:
5087            self._view.ui.btn_pred_multi_predict.setEnabled(True)
5088            gui_elements_to_show = [
5089                self._view.ui.lbl_pred_multi_prot_to_predict,
5090                self._view.ui.table_pred_multi_prot_to_predict,
5091                self._view.ui.btn_pred_multi_prot_to_predict_add,
5092                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5093                self._view.ui.lbl_pred_multi_advanced_config,
5094                self._view.ui.btn_pred_multi_advanced_config,
5095                self._view.ui.btn_pred_multi_predict,
5096            ]
5097            gui_elements_to_hide = [
5098                self._view.ui.lbl_pred_multi_prot_name_status,
5099                self._view.ui.btn_pred_multi_back,
5100                self._view.ui.btn_pred_multi_next,
5101                self._view.ui.lbl_pred_multi_prot_name,
5102                self._view.ui.txt_pred_multi_prot_name,
5103                self._view.ui.lbl_pred_multi_prot_seq,
5104                self._view.ui.txt_pred_multi_prot_seq,
5105                self._view.ui.lbl_pred_multi_prot_seq_status,
5106                self._view.ui.lbl_pred_multi_prot_seq_add,
5107                self._view.ui.btn_pred_multi_prot_seq_add,
5108                self._view.ui.lbl_pred_multi_prot_seq_overview,
5109                self._view.ui.list_pred_multi_prot_seq_overview,
5110                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5111                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5112                self._view.ui.btn_pred_multi_back_2,
5113                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5114            ]
5115            gui_utils.show_gui_elements(gui_elements_to_show)
5116            gui_utils.hide_gui_elements(gui_elements_to_hide)
5117            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5118
5119    def local_pred_multi_add_sequence_to_list(self) -> None:
5120        """Adds the entered sequence to the list of sequences of the protein."""
5121        self._view.ui.list_pred_multi_prot_seq_overview.addItem(
5122            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_multi_prot_seq.toPlainText()),
5123        )
5124        self.local_pred_multi_check_if_list_is_empty()
5125
5126    def local_pred_multi_remove_sequence_to_list(self) -> None:
5127        """Removes the entered sequence to the list of sequences of the protein."""
5128        self._view.ui.list_pred_multi_prot_seq_overview.takeItem(
5129            self._view.ui.list_pred_multi_prot_seq_overview.currentRow(),
5130        )
5131        self.local_pred_multi_check_if_list_is_empty()
5132        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)
5133
5134    def local_pred_multi_check_if_list_is_empty(self) -> None:
5135        """Checks if the list of sequences of the protein is empty."""
5136        if self._view.ui.list_pred_multi_prot_seq_overview.count() == 0:
5137            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5138        else:
5139            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(True)
5140
5141    def local_pred_multi_add(self) -> None:
5142        """Shows the gui elements for the protein name."""
5143        gui_elements_to_show = [
5144            self._view.ui.lbl_pred_multi_prot_to_predict,
5145            self._view.ui.table_pred_multi_prot_to_predict,
5146            self._view.ui.lbl_pred_multi_prot_name,
5147            self._view.ui.txt_pred_multi_prot_name,
5148            self._view.ui.lbl_pred_multi_prot_name_status,
5149            self._view.ui.btn_pred_multi_back,
5150            self._view.ui.btn_pred_multi_next,
5151        ]
5152        gui_elements_to_hide = [
5153            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5154            self._view.ui.btn_pred_multi_prot_to_predict_add,
5155            self._view.ui.lbl_pred_multi_prot_seq,
5156            self._view.ui.txt_pred_multi_prot_seq,
5157            self._view.ui.lbl_pred_multi_prot_seq_status,
5158            self._view.ui.lbl_pred_multi_prot_seq_add,
5159            self._view.ui.btn_pred_multi_prot_seq_add,
5160            self._view.ui.lbl_pred_multi_prot_seq_overview,
5161            self._view.ui.list_pred_multi_prot_seq_overview,
5162            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5163            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5164            self._view.ui.btn_pred_multi_back_2,
5165            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5166            self._view.ui.lbl_pred_multi_advanced_config,
5167            self._view.ui.btn_pred_multi_advanced_config,
5168            self._view.ui.btn_pred_multi_predict,
5169        ]
5170        gui_utils.show_gui_elements(gui_elements_to_show)
5171        gui_utils.hide_gui_elements(gui_elements_to_hide)
5172        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5173        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5174        self._view.ui.btn_pred_multi_next.setEnabled(False)
5175        self._view.ui.txt_pred_multi_prot_name.clear()
5176        styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5177        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5178            try:
5179                self._view.ui.table_pred_multi_prot_to_predict.currentItem().setSelected(False)
5180            except AttributeError:
5181                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")
5182
5183    def local_pred_multi_back(self) -> None:
5184        """Hides the gui elements for the protein name."""
5185        gui_elements_to_show = [
5186            self._view.ui.lbl_pred_multi_prot_to_predict,
5187            self._view.ui.table_pred_multi_prot_to_predict,
5188            self._view.ui.btn_pred_multi_prot_to_predict_add,
5189        ]
5190        gui_elements_to_hide = [
5191            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5192            self._view.ui.lbl_pred_multi_prot_name,
5193            self._view.ui.txt_pred_multi_prot_name,
5194            self._view.ui.lbl_pred_multi_prot_name_status,
5195            self._view.ui.btn_pred_multi_back,
5196            self._view.ui.btn_pred_multi_next,
5197            self._view.ui.lbl_pred_multi_prot_seq,
5198            self._view.ui.txt_pred_multi_prot_seq,
5199            self._view.ui.lbl_pred_multi_prot_seq_status,
5200            self._view.ui.lbl_pred_multi_prot_seq_add,
5201            self._view.ui.btn_pred_multi_prot_seq_add,
5202            self._view.ui.lbl_pred_multi_prot_seq_overview,
5203            self._view.ui.list_pred_multi_prot_seq_overview,
5204            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5205            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5206            self._view.ui.btn_pred_multi_back_2,
5207            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5208            self._view.ui.lbl_pred_multi_advanced_config,
5209            self._view.ui.btn_pred_multi_advanced_config,
5210            self._view.ui.btn_pred_multi_predict,
5211        ]
5212        gui_utils.show_gui_elements(gui_elements_to_show)
5213        gui_utils.hide_gui_elements(gui_elements_to_hide)
5214        self.local_pred_multi_check_if_table_is_empty()
5215
5216    def local_pred_multi_next(self) -> None:
5217        """Shows the gui elements for the protein sequence."""
5218        gui_elements_to_show = [
5219            self._view.ui.lbl_pred_multi_prot_to_predict,
5220            self._view.ui.table_pred_multi_prot_to_predict,
5221            self._view.ui.lbl_pred_multi_prot_name,
5222            self._view.ui.txt_pred_multi_prot_name,
5223            self._view.ui.lbl_pred_multi_prot_seq,
5224            self._view.ui.txt_pred_multi_prot_seq,
5225            self._view.ui.lbl_pred_multi_prot_seq_status,
5226            self._view.ui.lbl_pred_multi_prot_seq_add,
5227            self._view.ui.btn_pred_multi_prot_seq_add,
5228            self._view.ui.lbl_pred_multi_prot_seq_overview,
5229            self._view.ui.list_pred_multi_prot_seq_overview,
5230            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5231            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5232            self._view.ui.btn_pred_multi_back_2,
5233            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5234        ]
5235        gui_elements_to_hide = [
5236            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5237            self._view.ui.btn_pred_multi_prot_to_predict_add,
5238            self._view.ui.lbl_pred_multi_prot_name_status,
5239            self._view.ui.btn_pred_multi_back,
5240            self._view.ui.btn_pred_multi_next,
5241            self._view.ui.lbl_pred_multi_advanced_config,
5242            self._view.ui.btn_pred_multi_advanced_config,
5243            self._view.ui.btn_pred_multi_predict,
5244        ]
5245        gui_utils.show_gui_elements(gui_elements_to_show)
5246        gui_utils.hide_gui_elements(gui_elements_to_hide)
5247        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5248        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5249        self._view.ui.txt_pred_multi_prot_seq.clear()
5250        self._view.ui.list_pred_multi_prot_seq_overview.clear()
5251        self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5252        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)
5253        styles.color_button_not_ready(self._view.ui.btn_pred_multi_prot_to_predict_add_2)
5254
5255    def local_pred_multi_back_2(self) -> None:
5256        """Hides the gui elements for the protein sequence."""
5257        gui_elements_to_show = [
5258            self._view.ui.lbl_pred_multi_prot_to_predict,
5259            self._view.ui.table_pred_multi_prot_to_predict,
5260            self._view.ui.lbl_pred_multi_prot_name_status,
5261            self._view.ui.btn_pred_multi_back,
5262            self._view.ui.btn_pred_multi_next,
5263            self._view.ui.lbl_pred_multi_prot_name,
5264            self._view.ui.txt_pred_multi_prot_name,
5265        ]
5266        gui_elements_to_hide = [
5267            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5268            self._view.ui.btn_pred_multi_prot_to_predict_add,
5269            self._view.ui.lbl_pred_multi_prot_seq,
5270            self._view.ui.txt_pred_multi_prot_seq,
5271            self._view.ui.lbl_pred_multi_prot_seq_status,
5272            self._view.ui.lbl_pred_multi_prot_seq_add,
5273            self._view.ui.btn_pred_multi_prot_seq_add,
5274            self._view.ui.lbl_pred_multi_prot_seq_overview,
5275            self._view.ui.list_pred_multi_prot_seq_overview,
5276            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5277            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5278            self._view.ui.btn_pred_multi_back_2,
5279            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5280            self._view.ui.lbl_pred_multi_advanced_config,
5281            self._view.ui.btn_pred_multi_advanced_config,
5282            self._view.ui.btn_pred_multi_predict,
5283        ]
5284        gui_utils.show_gui_elements(gui_elements_to_show)
5285        gui_utils.hide_gui_elements(gui_elements_to_hide)
5286        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5287        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5288
5289    def local_pred_multi_prot_seq_overview_item_changed(self) -> None:
5290        """Enables the remove button of the list sequences of the protein."""
5291        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(True)
5292
5293    def local_pred_multi_prot_to_predict_item_changed(self) -> None:
5294        """Enables the remove button of the table proteins to predict."""
5295        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(True)
5296
5297    def local_pred_multi_prot_to_predict_add_2(self) -> None:
5298        """Adds the protein to the list of proteins to predict."""
5299        for i in range(self._view.ui.list_pred_multi_prot_seq_overview.count()):
5300            self._view.ui.table_pred_multi_prot_to_predict.setRowCount(
5301                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5302            )
5303            self._view.ui.table_pred_multi_prot_to_predict.insertRow(
5304                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5305            )
5306            tmp_chain_seq = (
5307                constants.chain_dict.get(i),
5308                self._view.ui.list_pred_multi_prot_seq_overview.item(i).text(),
5309            )
5310            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5311                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5312                0,
5313                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
5314            )
5315            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5316                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5317                1,
5318                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
5319            )
5320            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_multi_prot_name.text())
5321            self._view.ui.table_pred_multi_prot_to_predict.setVerticalHeaderItem(
5322                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5323                name_item,
5324            )
5325        self._view.ui.table_pred_multi_prot_to_predict.resizeColumnsToContents()
5326        self.local_pred_multi_check_if_table_is_empty()
5327        gui_elements_to_show = [
5328            self._view.ui.lbl_pred_multi_prot_to_predict,
5329            self._view.ui.table_pred_multi_prot_to_predict,
5330            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5331            self._view.ui.btn_pred_multi_prot_to_predict_add,
5332            self._view.ui.lbl_pred_multi_advanced_config,
5333            self._view.ui.btn_pred_multi_advanced_config,
5334            self._view.ui.btn_pred_multi_predict,
5335        ]
5336        gui_elements_to_hide = [
5337            self._view.ui.lbl_pred_multi_prot_name_status,
5338            self._view.ui.btn_pred_multi_back,
5339            self._view.ui.btn_pred_multi_next,
5340            self._view.ui.lbl_pred_multi_prot_name,
5341            self._view.ui.txt_pred_multi_prot_name,
5342            self._view.ui.lbl_pred_multi_prot_seq,
5343            self._view.ui.txt_pred_multi_prot_seq,
5344            self._view.ui.lbl_pred_multi_prot_seq_status,
5345            self._view.ui.lbl_pred_multi_prot_seq_add,
5346            self._view.ui.btn_pred_multi_prot_seq_add,
5347            self._view.ui.lbl_pred_multi_prot_seq_overview,
5348            self._view.ui.list_pred_multi_prot_seq_overview,
5349            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5350            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5351            self._view.ui.btn_pred_multi_back_2,
5352            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5353        ]
5354        gui_utils.show_gui_elements(gui_elements_to_show)
5355        gui_utils.hide_gui_elements(gui_elements_to_hide)
5356        self._init_local_pred_multi_page()
5357        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5358
5359    def local_pred_multi_remove(self) -> None:
5360        """Removes the selected protein from the list of proteins to predict."""
5361        self._view.ui.table_pred_multi_prot_to_predict.removeRow(
5362            self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5363        )
5364        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5365            prot_name = self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(
5366                self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5367            ).text()
5368            for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount()):
5369                if self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
5370                    self._view.ui.table_pred_multi_prot_to_predict.setItem(
5371                        i,
5372                        0,
5373                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
5374                    )
5375        self.local_pred_multi_check_if_table_is_empty()
5376        gui_elements_to_show = [
5377            self._view.ui.lbl_pred_multi_prot_to_predict,
5378            self._view.ui.table_pred_multi_prot_to_predict,
5379            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5380            self._view.ui.btn_pred_multi_prot_to_predict_add,
5381            self._view.ui.lbl_pred_multi_advanced_config,
5382            self._view.ui.btn_pred_multi_advanced_config,
5383            self._view.ui.btn_pred_multi_predict,
5384        ]
5385        gui_elements_to_hide = [
5386            self._view.ui.lbl_pred_multi_prot_name_status,
5387            self._view.ui.btn_pred_multi_back,
5388            self._view.ui.btn_pred_multi_next,
5389            self._view.ui.lbl_pred_multi_prot_name,
5390            self._view.ui.txt_pred_multi_prot_name,
5391            self._view.ui.lbl_pred_multi_prot_seq,
5392            self._view.ui.txt_pred_multi_prot_seq,
5393            self._view.ui.lbl_pred_multi_prot_seq_status,
5394            self._view.ui.lbl_pred_multi_prot_seq_add,
5395            self._view.ui.btn_pred_multi_prot_seq_add,
5396            self._view.ui.lbl_pred_multi_prot_seq_overview,
5397            self._view.ui.list_pred_multi_prot_seq_overview,
5398            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5399            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5400            self._view.ui.btn_pred_multi_back_2,
5401            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5402        ]
5403        gui_utils.show_gui_elements(gui_elements_to_show)
5404        gui_utils.hide_gui_elements(gui_elements_to_hide)
5405        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5406        self.local_pred_multi_check_if_table_is_empty()
5407
5408    # </editor-fold>
5409
5410    # <editor-fold desc="Monomer prediction + analysis">
5411    def _init_mono_pred_analysis_page(self) -> None:
5412        """Clears all text boxes and sets default values for the gui elements."""
5413        # <editor-fold desc="Prediction section">
5414        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5415        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5416        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
5417            self._view.ui.table_pred_analysis_mono_prot_to_predict.removeRow(i)
5418        # sets up defaults: Prediction
5419        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5420        self._view.ui.btn_pred_analysis_mono_add_protein.setEnabled(False)
5421        self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("")
5422        self._view.ui.lbl_pred_analysis_mono_seq_name_status.setText("")
5423
5424        # </editor-fold>
5425
5426        # <editor-fold desc="Analysis section">
5427        self._view.ui.list_pred_analysis_mono_overview.clear()
5428        self._view.ui.btn_pred_analysis_mono_remove.hide()
5429
5430        # </editor-fold>
5431
5432    def display_monomer_pred_analysis(self) -> None:
5433        """Displays the monomer prediction + analysis page."""
5434        # checks internet connection
5435        if not tools.check_internet_connectivity():
5436            gui_utils.no_internet_dialog()
5437            return
5438
5439        self._init_mono_pred_analysis_page()
5440        self._view.ui.table_pred_analysis_mono_prot_to_predict.clear()
5441        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5442            0,
5443            QtWidgets.QTableWidgetItem("Chain"),
5444        )
5445        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5446            1,
5447            QtWidgets.QTableWidgetItem("Sequence"),
5448        )
5449        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5450        gui_elements_to_show = [
5451            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5452            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5453            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5454        ]
5455        gui_elements_to_hide = [
5456            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5457            self._view.ui.lbl_pred_analysis_mono_prot_name,
5458            self._view.ui.txt_pred_analysis_mono_prot_name,
5459            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5460            self._view.ui.btn_pred_analysis_mono_back,
5461            self._view.ui.btn_pred_analysis_mono_next,
5462            self._view.ui.lbl_pred_analysis_mono_seq_name,
5463            self._view.ui.txt_pred_analysis_mono_seq_name,
5464            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5465            self._view.ui.btn_pred_analysis_mono_back_2,
5466            self._view.ui.btn_pred_analysis_mono_add_protein,
5467            self._view.ui.lbl_pred_mono_advanced_config_2,
5468            self._view.ui.btn_pred_mono_advanced_config_2,
5469            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5470            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5471        ]
5472        gui_utils.show_gui_elements(gui_elements_to_show)
5473        gui_utils.hide_gui_elements(gui_elements_to_hide)
5474        if self._view.ui.tabWidget.currentIndex() == 1:
5475            self._view.ui.tabWidget.setCurrentIndex(0)
5476        self._view.ui.tabWidget.setTabEnabled(1, False)
5477        self._view.ui.tabWidget.setTabEnabled(0, True)
5478        tools.switch_page(
5479            self._view.ui.stackedWidget,
5480            self._view.ui.lbl_page_title,
5481            21,
5482            "Monomer Prediction + Analysis",
5483        )
5484        self.last_sidebar_button = styles.color_sidebar_buttons(
5485            self.last_sidebar_button,
5486            self._view.ui.btn_pred_analysis_monomer_page,
5487        )
5488        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEnabled(True)
5489
5490    # <editor-fold desc="Sections">
5491
5492    # <editor-fold desc="Prediction section">
5493    def mono_pred_analysis_validate_protein_name(self) -> None:
5494        """Validates the input of the protein name in real-time."""
5495        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5496            self._view.ui.txt_pred_analysis_mono_prot_name.text(),
5497            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5498        ):
5499            self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("Protein name already used.")
5500            self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5501            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5502        else:
5503            self._view.ui.btn_pred_analysis_mono_next.setEnabled(True)
5504            tools.validate_protein_name(
5505                self._view.ui.txt_pred_analysis_mono_prot_name,
5506                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5507                self._view.ui.btn_pred_analysis_mono_next,
5508            )
5509
5510    def mono_pred_analysis_validate_protein_sequence(self) -> None:
5511        """Validates the input of the protein sequence in real-time."""
5512        tools.validate_protein_sequence(
5513            self._view.ui.txt_pred_analysis_mono_seq_name,
5514            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5515            self._view.ui.btn_pred_analysis_mono_add_protein,
5516        )
5517
5518    def mono_pred_analysis_check_if_table_is_empty(self) -> None:
5519        """Checks if the table proteins to predict is empty."""
5520        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() == 0:
5521            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_go_analysis_setup)
5522            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(False)
5523            gui_elements_to_show = [
5524                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5525                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5526                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5527            ]
5528            gui_elements_to_hide = [
5529                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5530                self._view.ui.lbl_pred_analysis_mono_prot_name,
5531                self._view.ui.txt_pred_analysis_mono_prot_name,
5532                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5533                self._view.ui.btn_pred_analysis_mono_back,
5534                self._view.ui.btn_pred_analysis_mono_next,
5535                self._view.ui.lbl_pred_analysis_mono_seq_name,
5536                self._view.ui.txt_pred_analysis_mono_seq_name,
5537                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5538                self._view.ui.btn_pred_analysis_mono_back_2,
5539                self._view.ui.btn_pred_analysis_mono_add_protein,
5540                self._view.ui.lbl_pred_mono_advanced_config_2,
5541                self._view.ui.btn_pred_mono_advanced_config_2,
5542                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5543                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5544            ]
5545            gui_utils.show_gui_elements(gui_elements_to_show)
5546            gui_utils.hide_gui_elements(gui_elements_to_hide)
5547        else:
5548            gui_elements_to_show = [
5549                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5550                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5551                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5552                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5553                self._view.ui.lbl_pred_mono_advanced_config_2,
5554                self._view.ui.btn_pred_mono_advanced_config_2,
5555                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5556                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5557            ]
5558            gui_elements_to_hide = [
5559                self._view.ui.lbl_pred_analysis_mono_prot_name,
5560                self._view.ui.txt_pred_analysis_mono_prot_name,
5561                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5562                self._view.ui.btn_pred_analysis_mono_back,
5563                self._view.ui.btn_pred_analysis_mono_next,
5564                self._view.ui.lbl_pred_analysis_mono_seq_name,
5565                self._view.ui.txt_pred_analysis_mono_seq_name,
5566                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5567                self._view.ui.btn_pred_analysis_mono_back_2,
5568                self._view.ui.btn_pred_analysis_mono_add_protein,
5569            ]
5570            gui_utils.show_gui_elements(gui_elements_to_show)
5571            gui_utils.hide_gui_elements(gui_elements_to_hide)
5572            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)
5573
5574    def setup_defaults_monomer_prediction_analysis(self) -> None:
5575        """Sets up default values for the prediction tab."""
5576        # clears everything
5577        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5578        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5579        # sets up defaults: Prediction
5580        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5581        self._view.ui.btn_pred_analysis_mono_add_protein.setEnabled(False)
5582        self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("")
5583        self._view.ui.lbl_pred_analysis_mono_seq_name_status.setText("")
5584
5585    def mono_pred_analysis_add_seq_to_predict(self) -> None:
5586        """Shows the gui elements for the protein name."""
5587        gui_elements_to_show = [
5588            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5589            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5590            self._view.ui.lbl_pred_analysis_mono_prot_name,
5591            self._view.ui.txt_pred_analysis_mono_prot_name,
5592            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5593            self._view.ui.btn_pred_analysis_mono_back,
5594            self._view.ui.btn_pred_analysis_mono_next,
5595        ]
5596        gui_utils.enable_text_box(
5597            self._view.ui.txt_pred_analysis_mono_prot_name,
5598            self._view.ui.lbl_pred_analysis_mono_prot_name,
5599        )
5600        gui_elements_to_hide = [
5601            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5602            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5603            self._view.ui.lbl_pred_analysis_mono_seq_name,
5604            self._view.ui.txt_pred_analysis_mono_seq_name,
5605            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5606            self._view.ui.btn_pred_analysis_mono_back_2,
5607            self._view.ui.btn_pred_analysis_mono_add_protein,
5608            self._view.ui.lbl_pred_mono_advanced_config_2,
5609            self._view.ui.btn_pred_mono_advanced_config_2,
5610            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5611            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5612        ]
5613        gui_utils.disable_text_box(
5614            self._view.ui.txt_pred_analysis_mono_seq_name,
5615            self._view.ui.lbl_pred_analysis_mono_seq_name,
5616        )
5617        gui_utils.show_gui_elements(gui_elements_to_show)
5618        gui_utils.hide_gui_elements(gui_elements_to_hide)
5619        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5620        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5621        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5622        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() > 0:
5623            try:
5624                self._view.ui.table_pred_analysis_mono_prot_to_predict.currentItem().setSelected(False)
5625            except AttributeError:
5626                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
5627
5628    def mono_pred_analysis_back(self) -> None:
5629        """Hides the gui elements for the protein name."""
5630        gui_elements_to_show = [
5631            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5632            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5633            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5634            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5635        ]
5636        gui_elements_to_hide = [
5637            self._view.ui.lbl_pred_analysis_mono_prot_name,
5638            self._view.ui.txt_pred_analysis_mono_prot_name,
5639            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5640            self._view.ui.btn_pred_analysis_mono_back,
5641            self._view.ui.btn_pred_analysis_mono_next,
5642            self._view.ui.lbl_pred_analysis_mono_seq_name,
5643            self._view.ui.txt_pred_analysis_mono_seq_name,
5644            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5645            self._view.ui.btn_pred_analysis_mono_back_2,
5646            self._view.ui.btn_pred_analysis_mono_add_protein,
5647            self._view.ui.lbl_pred_mono_advanced_config_2,
5648            self._view.ui.btn_pred_mono_advanced_config_2,
5649            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5650            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5651        ]
5652        gui_utils.show_gui_elements(gui_elements_to_show)
5653        gui_utils.hide_gui_elements(gui_elements_to_hide)
5654        self.mono_pred_analysis_check_if_table_is_empty()
5655        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5656
5657    def mono_pred_analysis_next(self) -> None:
5658        """Shows the gui elements for the protein sequence."""
5659        gui_elements_to_show = [
5660            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5661            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5662            self._view.ui.lbl_pred_analysis_mono_prot_name,
5663            self._view.ui.txt_pred_analysis_mono_prot_name,
5664            self._view.ui.lbl_pred_analysis_mono_seq_name,
5665            self._view.ui.txt_pred_analysis_mono_seq_name,
5666            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5667            self._view.ui.btn_pred_analysis_mono_back_2,
5668            self._view.ui.btn_pred_analysis_mono_add_protein,
5669        ]
5670        gui_utils.enable_text_box(
5671            self._view.ui.txt_pred_analysis_mono_seq_name,
5672            self._view.ui.lbl_pred_analysis_mono_seq_name,
5673        )
5674        gui_elements_to_hide = [
5675            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5676            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5677            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5678            self._view.ui.btn_pred_analysis_mono_back,
5679            self._view.ui.btn_pred_analysis_mono_next,
5680            self._view.ui.lbl_pred_mono_advanced_config_2,
5681            self._view.ui.btn_pred_mono_advanced_config_2,
5682            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5683            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5684        ]
5685        gui_utils.disable_text_box(
5686            self._view.ui.txt_pred_analysis_mono_prot_name,
5687            self._view.ui.lbl_pred_analysis_mono_prot_name,
5688        )
5689        gui_utils.show_gui_elements(gui_elements_to_show)
5690        gui_utils.hide_gui_elements(gui_elements_to_hide)
5691        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5692
5693    def mono_pred_analysis_back_2(self) -> None:
5694        """Hides the gui elements for the protein sequence."""
5695        gui_elements_to_show = [
5696            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5697            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5698            self._view.ui.lbl_pred_analysis_mono_prot_name,
5699            self._view.ui.txt_pred_analysis_mono_prot_name,
5700            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5701            self._view.ui.btn_pred_analysis_mono_back,
5702            self._view.ui.btn_pred_analysis_mono_next,
5703        ]
5704        gui_elements_to_hide = [
5705            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5706            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5707            self._view.ui.lbl_pred_analysis_mono_seq_name,
5708            self._view.ui.txt_pred_analysis_mono_seq_name,
5709            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5710            self._view.ui.btn_pred_analysis_mono_back_2,
5711            self._view.ui.btn_pred_analysis_mono_add_protein,
5712            self._view.ui.lbl_pred_mono_advanced_config_2,
5713            self._view.ui.btn_pred_mono_advanced_config_2,
5714            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5715            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5716        ]
5717        gui_utils.enable_text_box(
5718            self._view.ui.txt_pred_analysis_mono_prot_name,
5719            self._view.ui.lbl_pred_analysis_mono_prot_name,
5720        )
5721        gui_utils.disable_text_box(
5722            self._view.ui.txt_pred_analysis_mono_seq_name,
5723            self._view.ui.lbl_pred_analysis_mono_seq_name,
5724        )
5725        gui_utils.show_gui_elements(gui_elements_to_show)
5726        gui_utils.hide_gui_elements(gui_elements_to_hide)
5727
5728    def mono_pred_analysis_add_protein(self) -> None:
5729        """Adds the protein to the list of proteins to predict."""
5730        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5731            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5732        )
5733        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5734            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5735        )
5736        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5737            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5738            0,
5739            QtWidgets.QTableWidgetItem("A"),
5740        )
5741        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5742            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5743            1,
5744            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5745        )
5746        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5747            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5748            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5749        )
5750        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5751        self.mono_pred_analysis_check_if_table_is_empty()
5752        gui_elements_to_show = [
5753            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5754            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5755            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5756            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5757            self._view.ui.lbl_pred_mono_advanced_config_2,
5758            self._view.ui.btn_pred_mono_advanced_config_2,
5759            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5760            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5761        ]
5762        gui_utils.enable_text_box(
5763            self._view.ui.txt_pred_analysis_mono_prot_name,
5764            self._view.ui.lbl_pred_analysis_mono_prot_name,
5765        )
5766        gui_elements_to_hide = [
5767            self._view.ui.lbl_pred_analysis_mono_prot_name,
5768            self._view.ui.txt_pred_analysis_mono_prot_name,
5769            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5770            self._view.ui.btn_pred_analysis_mono_back,
5771            self._view.ui.btn_pred_analysis_mono_next,
5772            self._view.ui.lbl_pred_analysis_mono_seq_name,
5773            self._view.ui.txt_pred_analysis_mono_seq_name,
5774            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5775            self._view.ui.btn_pred_analysis_mono_back_2,
5776            self._view.ui.btn_pred_analysis_mono_add_protein,
5777        ]
5778        gui_utils.show_gui_elements(gui_elements_to_show)
5779        gui_utils.hide_gui_elements(gui_elements_to_hide)
5780        self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)
5781        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5782        self.setup_defaults_monomer_prediction()
5783
5784    def mono_pred_analysis_prediction_overview_item_clicked(self) -> None:
5785        """Enables the remove button."""
5786        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(True)
5787
5788    def mono_pred_analysis_add_protein_to_predict(self) -> None:
5789        """Needs to be removed."""
5790        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5791            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5792        )
5793        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5794            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5795        )
5796        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5797            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5798            0,
5799            QtWidgets.QTableWidgetItem("A"),
5800        )
5801        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5802            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5803            1,
5804            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5805        )
5806        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5807            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5808            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5809        )
5810        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5811        self.mono_pred_analysis_check_if_table_is_empty()
5812        self.setup_defaults_monomer_prediction_analysis()
5813
5814    def mono_pred_analysis_remove_protein_to_predict(self) -> None:
5815        """Removes the selected protein from the list of proteins to predict."""
5816        self._view.ui.table_pred_analysis_mono_prot_to_predict.removeRow(
5817            self._view.ui.table_pred_analysis_mono_prot_to_predict.currentRow(),
5818        )
5819        self.mono_pred_analysis_check_if_table_is_empty()
5820        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5821
5822    # </editor-fold>
5823
5824    # <editor-fold desc="Analysis section">
5825    def mono_pred_analysis_structure_analysis_add(self) -> None:
5826        """Shows the gui elements for the selection of the two proteins."""
5827        gui_elements_to_show = [
5828            self._view.ui.lbl_pred_analysis_mono_overview,
5829            self._view.ui.list_pred_analysis_mono_overview,
5830            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5831            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5832            self._view.ui.lbl_analysis_batch_vs_2,
5833            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5834            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5835            self._view.ui.btn_pred_analysis_mono_back_3,
5836            self._view.ui.btn_pred_analysis_mono_next_2,
5837        ]
5838        gui_elements_to_hide = [
5839            self._view.ui.btn_pred_analysis_mono_remove,
5840            self._view.ui.btn_pred_analysis_mono_add,
5841            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5842            self._view.ui.list_pred_analysis_mono_ref_chains,
5843            self._view.ui.btn_pred_analysis_mono_back_4,
5844            self._view.ui.btn_pred_analysis_mono_next_3,
5845            self._view.ui.lbl_pred_analysis_mono_model_chains,
5846            self._view.ui.list_pred_analysis_mono_model_chains,
5847            self._view.ui.btn_pred_analysis_mono_back_5,
5848            self._view.ui.btn_pred_analysis_mono_next_4,
5849            self._view.ui.lbl_pred_analysis_mono_images,
5850            self._view.ui.cb_pred_analysis_mono_images,
5851            self._view.ui.btn_pred_analysis_mono_start,
5852            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5853        ]
5854        gui_utils.show_gui_elements(gui_elements_to_show)
5855        gui_utils.hide_gui_elements(gui_elements_to_hide)
5856        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.clear()
5857        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.clear()
5858        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5859        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")
5860        self.fill_mono_pred_analysis_protein_boxes()
5861        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5862            try:
5863                self._view.ui.list_pred_analysis_mono_overview.currentItem().setSelected(False)
5864            except AttributeError:
5865                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
5866
5867    def mono_pred_analysis_structure_analysis_back_3(self) -> None:
5868        """Hides the gui elements to select the two proteins."""
5869        gui_elements_to_show = [
5870            self._view.ui.lbl_pred_analysis_mono_overview,
5871            self._view.ui.list_pred_analysis_mono_overview,
5872            self._view.ui.btn_pred_analysis_mono_add,
5873            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5874        ]
5875        gui_elements_to_hide = [
5876            self._view.ui.btn_pred_analysis_mono_remove,
5877            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5878            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5879            self._view.ui.lbl_analysis_batch_vs_2,
5880            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5881            self._view.ui.list_pred_analysis_mono_ref_chains,
5882            self._view.ui.btn_pred_analysis_mono_back_4,
5883            self._view.ui.btn_pred_analysis_mono_next_3,
5884            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5885            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5886            self._view.ui.btn_pred_analysis_mono_back_3,
5887            self._view.ui.btn_pred_analysis_mono_next_2,
5888            self._view.ui.lbl_pred_analysis_mono_model_chains,
5889            self._view.ui.list_pred_analysis_mono_model_chains,
5890            self._view.ui.btn_pred_analysis_mono_back_5,
5891            self._view.ui.btn_pred_analysis_mono_next_4,
5892            self._view.ui.lbl_pred_analysis_mono_images,
5893            self._view.ui.cb_pred_analysis_mono_images,
5894            self._view.ui.btn_pred_analysis_mono_start,
5895        ]
5896        gui_utils.show_gui_elements(gui_elements_to_show)
5897        gui_utils.hide_gui_elements(gui_elements_to_hide)
5898        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5899            self._view.ui.btn_pred_analysis_mono_remove.show()
5900            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
5901            self._view.ui.btn_pred_analysis_mono_start.show()
5902            self._view.ui.lbl_pred_analysis_mono_images.show()
5903            self._view.ui.cb_pred_analysis_mono_images.show()
5904
5905    def mono_pred_analysis_structure_analysis_next_3(self) -> None:
5906        """Shows the gui elements to select the chains of protein 2."""
5907        gui_elements_to_show = [
5908            self._view.ui.lbl_pred_analysis_mono_overview,
5909            self._view.ui.list_pred_analysis_mono_overview,
5910            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5911            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5912            self._view.ui.lbl_analysis_batch_vs_2,
5913            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5914            self._view.ui.list_pred_analysis_mono_ref_chains,
5915            self._view.ui.lbl_pred_analysis_mono_model_chains,
5916            self._view.ui.list_pred_analysis_mono_model_chains,
5917            self._view.ui.btn_pred_analysis_mono_back_5,
5918            self._view.ui.btn_pred_analysis_mono_next_4,
5919        ]
5920        gui_elements_to_hide = [
5921            self._view.ui.btn_pred_analysis_mono_remove,
5922            self._view.ui.btn_pred_analysis_mono_add,
5923            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5924            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5925            self._view.ui.btn_pred_analysis_mono_back_3,
5926            self._view.ui.btn_pred_analysis_mono_next_2,
5927            self._view.ui.btn_pred_analysis_mono_back_4,
5928            self._view.ui.btn_pred_analysis_mono_next_3,
5929            self._view.ui.lbl_pred_analysis_mono_images,
5930            self._view.ui.cb_pred_analysis_mono_images,
5931            self._view.ui.btn_pred_analysis_mono_start,
5932            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5933        ]
5934        gui_utils.show_gui_elements(gui_elements_to_show)
5935        gui_utils.hide_gui_elements(gui_elements_to_hide)
5936        self._view.ui.list_pred_analysis_mono_model_chains.clear()
5937        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(False)
5938        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
5939
5940        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
5941            if (
5942                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text()
5943                == self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText()
5944            ):
5945                self._view.ui.list_pred_analysis_mono_model_chains.addItem(
5946                    self._view.ui.table_pred_analysis_mono_prot_to_predict.item(i, 0).text(),
5947                )
5948        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 0:
5949            tmp_protein = self._current_project.search_protein(
5950                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
5951            )
5952            for tmp_chain in tmp_protein.chains:
5953                if tmp_chain.chain_type == "protein_chain":
5954                    self._view.ui.list_pred_analysis_mono_model_chains.addItem(tmp_chain.chain_letter)
5955        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 1:
5956            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5957                f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5958            )
5959        else:
5960            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5961                f"Select {len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems())} chains "
5962                f"in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5963            )
5964
5965    def mono_pred_analysis_structure_analysis_back_4(self) -> None:
5966        """Hides the gui elements to select the chains in protein 1."""
5967        gui_elements_to_show = [
5968            self._view.ui.lbl_pred_analysis_mono_overview,
5969            self._view.ui.list_pred_analysis_mono_overview,
5970            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5971            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5972            self._view.ui.lbl_analysis_batch_vs_2,
5973            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5974            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5975            self._view.ui.btn_pred_analysis_mono_back_3,
5976            self._view.ui.btn_pred_analysis_mono_next_2,
5977            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5978        ]
5979        gui_elements_to_hide = [
5980            self._view.ui.btn_pred_analysis_mono_remove,
5981            self._view.ui.btn_pred_analysis_mono_add,
5982            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5983            self._view.ui.list_pred_analysis_mono_ref_chains,
5984            self._view.ui.btn_pred_analysis_mono_back_4,
5985            self._view.ui.btn_pred_analysis_mono_next_3,
5986            self._view.ui.lbl_pred_analysis_mono_model_chains,
5987            self._view.ui.list_pred_analysis_mono_model_chains,
5988            self._view.ui.btn_pred_analysis_mono_back_5,
5989            self._view.ui.btn_pred_analysis_mono_next_4,
5990            self._view.ui.lbl_pred_analysis_mono_images,
5991            self._view.ui.cb_pred_analysis_mono_images,
5992            self._view.ui.btn_pred_analysis_mono_start,
5993        ]
5994        gui_utils.show_gui_elements(gui_elements_to_show)
5995        gui_utils.hide_gui_elements(gui_elements_to_hide)
5996        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5997        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")
5998
5999    def mono_pred_analysis_structure_analysis_next_4(self) -> None:
6000        """Adds the protein pair to the list of protein pairs to analyze."""
6001        gui_elements_to_show = [
6002            self._view.ui.btn_pred_analysis_mono_remove,
6003            self._view.ui.btn_pred_analysis_mono_add,
6004            self._view.ui.lbl_pred_analysis_mono_overview,
6005            self._view.ui.list_pred_analysis_mono_overview,
6006            self._view.ui.lbl_pred_analysis_mono_images,
6007            self._view.ui.cb_pred_analysis_mono_images,
6008            self._view.ui.btn_pred_analysis_mono_start,
6009            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6010        ]
6011        gui_elements_to_hide = [
6012            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6013            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6014            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6015            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6016            self._view.ui.lbl_analysis_batch_vs_2,
6017            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6018            self._view.ui.list_pred_analysis_mono_ref_chains,
6019            self._view.ui.lbl_pred_analysis_mono_model_chains,
6020            self._view.ui.list_pred_analysis_mono_model_chains,
6021            self._view.ui.btn_pred_analysis_mono_back_3,
6022            self._view.ui.btn_pred_analysis_mono_next_2,
6023            self._view.ui.btn_pred_analysis_mono_back_4,
6024            self._view.ui.btn_pred_analysis_mono_next_3,
6025            self._view.ui.btn_pred_analysis_mono_back_5,
6026            self._view.ui.btn_pred_analysis_mono_next_4,
6027        ]
6028        gui_utils.show_gui_elements(gui_elements_to_show)
6029        gui_utils.hide_gui_elements(gui_elements_to_hide)
6030        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6031        prot_1_chains = []
6032        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6033            prot_1_chains.append(chain.text())
6034        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6035        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6036        prot_2_chains = []
6037        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6038            prot_2_chains.append(chain.text())
6039        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6040        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6041        item = QtWidgets.QListWidgetItem(analysis_name)
6042        self._view.ui.list_pred_analysis_mono_overview.addItem(item)
6043        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6044
6045    def mono_pred_analysis_structure_analysis_back_5(self) -> None:
6046        """Hides the gui elements to select the chains in protein 2."""
6047        gui_elements_to_show = [
6048            self._view.ui.lbl_pred_analysis_mono_overview,
6049            self._view.ui.list_pred_analysis_mono_overview,
6050            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6051            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6052            self._view.ui.lbl_analysis_batch_vs_2,
6053            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6054            self._view.ui.list_pred_analysis_mono_ref_chains,
6055            self._view.ui.btn_pred_analysis_mono_back_4,
6056            self._view.ui.btn_pred_analysis_mono_next_3,
6057        ]
6058        gui_elements_to_hide = [
6059            self._view.ui.btn_pred_analysis_mono_remove,
6060            self._view.ui.btn_pred_analysis_mono_add,
6061            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6062            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6063            self._view.ui.btn_pred_analysis_mono_back_3,
6064            self._view.ui.btn_pred_analysis_mono_next_2,
6065            self._view.ui.btn_pred_analysis_mono_back_5,
6066            self._view.ui.btn_pred_analysis_mono_next_4,
6067            self._view.ui.lbl_pred_analysis_mono_images,
6068            self._view.ui.cb_pred_analysis_mono_images,
6069            self._view.ui.btn_pred_analysis_mono_start,
6070            self._view.ui.lbl_pred_analysis_mono_model_chains,
6071            self._view.ui.list_pred_analysis_mono_model_chains,
6072            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6073        ]
6074        gui_utils.show_gui_elements(gui_elements_to_show)
6075        gui_utils.hide_gui_elements(gui_elements_to_hide)
6076        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(True)
6077
6078        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText())
6079        # for tmp_chain in tmp_protein.chains:
6080        #     if tmp_chain.chain_type == "protein_chain":
6081        #         self._view.ui.list_pred_analysis_mono_ref_chains.addItem(tmp_chain.chain_letter)
6082
6083    def mono_pred_analysis_structure_analysis_overview_clicked(self) -> None:
6084        """Enables the remove button."""
6085        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(True)
6086
6087    def fill_mono_pred_analysis_protein_boxes(self) -> None:
6088        """Fills the combo box of the protein structures."""
6089        protein_names = []
6090        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
6091            protein_names.append(self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text())
6092        for tmp_protein in self._current_project.proteins:
6093            protein_names.append(tmp_protein.get_molecule_object())
6094        protein_names.insert(0, "")
6095        self._view.ui.box_pred_analysis_mono_prot_struct_1.clear()
6096        self._view.ui.box_pred_analysis_mono_prot_struct_2.clear()
6097        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_1, protein_names)
6098        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_2, protein_names)
6099
6100    def remove_mono_pred_analysis_analysis_run(self) -> None:
6101        """Removes a selected protein pair form the list of protein pairs to analyze."""
6102        self._view.ui.list_pred_analysis_mono_overview.takeItem(
6103            self._view.ui.list_pred_analysis_mono_overview.currentRow(),
6104        )
6105        gui_elements_to_show = [
6106            self._view.ui.lbl_pred_analysis_mono_overview,
6107            self._view.ui.list_pred_analysis_mono_overview,
6108            self._view.ui.btn_pred_analysis_mono_add,
6109            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6110        ]
6111        gui_elements_to_hide = [
6112            self._view.ui.btn_pred_analysis_mono_remove,
6113            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6114            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6115            self._view.ui.lbl_analysis_batch_vs_2,
6116            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6117            self._view.ui.list_pred_analysis_mono_ref_chains,
6118            self._view.ui.btn_pred_analysis_mono_back_4,
6119            self._view.ui.btn_pred_analysis_mono_next_3,
6120            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6121            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6122            self._view.ui.btn_pred_analysis_mono_back_3,
6123            self._view.ui.btn_pred_analysis_mono_next_2,
6124            self._view.ui.lbl_pred_analysis_mono_model_chains,
6125            self._view.ui.list_pred_analysis_mono_model_chains,
6126            self._view.ui.btn_pred_analysis_mono_back_5,
6127            self._view.ui.btn_pred_analysis_mono_next_4,
6128            self._view.ui.lbl_pred_analysis_mono_images,
6129            self._view.ui.cb_pred_analysis_mono_images,
6130            self._view.ui.btn_pred_analysis_mono_start,
6131        ]
6132        gui_utils.show_gui_elements(gui_elements_to_show)
6133        gui_utils.hide_gui_elements(gui_elements_to_hide)
6134        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6135            self._view.ui.btn_pred_analysis_mono_remove.show()
6136            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6137            self._view.ui.btn_pred_analysis_mono_start.show()
6138            self._view.ui.lbl_pred_analysis_mono_images.show()
6139            self._view.ui.cb_pred_analysis_mono_images.show()
6140        # if self._view.ui.list_pred_analysis_mono_overview.count() == 0:
6141        #
6142        #     self._view.ui.btn_pred_analysis_mono_back_pred_setup.show()
6143        #     self._view.ui.btn_pred_analysis_mono_remove.hide()
6144
6145    def check_mono_pred_analysis_if_same_no_of_chains_selected(self) -> None:
6146        """Checks if the same number of chains were selected."""
6147        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6148        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems()):
6149            self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(True)
6150
6151        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6152        prot_1_chains = []
6153        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6154            prot_1_chains.append(chain.text())
6155        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6156        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6157        prot_2_chains = []
6158        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6159            prot_2_chains.append(chain.text())
6160        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6161        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6162        for tmp_row in range(self._view.ui.list_pred_analysis_mono_overview.count()):
6163            if analysis_name == self._view.ui.list_pred_analysis_mono_overview.item(tmp_row).text():
6164                self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6165                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next_4)
6166                return
6167
6168    def check_mono_pred_analysis_if_prot_structs_are_filled(self) -> None:
6169        """Checks if two proteins were selected."""
6170        prot_1 = self._view.ui.box_pred_analysis_mono_prot_struct_1.itemText(
6171            self._view.ui.box_pred_analysis_mono_prot_struct_1.currentIndex(),
6172        )
6173        prot_2 = self._view.ui.box_pred_analysis_mono_prot_struct_2.itemText(
6174            self._view.ui.box_pred_analysis_mono_prot_struct_2.currentIndex(),
6175        )
6176        if prot_1 != "" and prot_2 != "":
6177            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(True)
6178        else:
6179            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(False)
6180
6181    def count_mono_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
6182        """Counts the number of chains selected in protein 1."""
6183        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems())
6184        if self.no_of_selected_chains > 0:
6185            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(True)
6186        else:
6187            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(False)
6188
6189    # </editor-fold>
6190
6191    # </editor-fold>
6192
6193    def switch_monomer_pred_analysis_tab(self) -> None:
6194        """Switches the tabs from prediction to analysis and vice versa."""
6195        if self._view.ui.tabWidget.currentIndex() == 0:
6196            # goes from prediction to analysis
6197            self._view.ui.tabWidget.setTabEnabled(1, True)
6198            self._view.ui.tabWidget.setTabEnabled(0, False)
6199            self._view.ui.tabWidget.setCurrentIndex(1)
6200            gui_elements_to_show = [
6201                self._view.ui.lbl_pred_analysis_mono_overview,
6202                self._view.ui.list_pred_analysis_mono_overview,
6203                self._view.ui.btn_pred_analysis_mono_add,
6204                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6205            ]
6206            gui_elements_to_hide = [
6207                self._view.ui.btn_pred_analysis_mono_remove,
6208                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6209                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6210                self._view.ui.lbl_analysis_batch_vs_2,
6211                self._view.ui.lbl_pred_analysis_mono_ref_chains,
6212                self._view.ui.list_pred_analysis_mono_ref_chains,
6213                self._view.ui.btn_pred_analysis_mono_back_4,
6214                self._view.ui.btn_pred_analysis_mono_next_3,
6215                self._view.ui.box_pred_analysis_mono_prot_struct_1,
6216                self._view.ui.box_pred_analysis_mono_prot_struct_2,
6217                self._view.ui.btn_pred_analysis_mono_back_3,
6218                self._view.ui.btn_pred_analysis_mono_next_2,
6219                self._view.ui.lbl_pred_analysis_mono_model_chains,
6220                self._view.ui.list_pred_analysis_mono_model_chains,
6221                self._view.ui.btn_pred_analysis_mono_back_5,
6222                self._view.ui.btn_pred_analysis_mono_next_4,
6223                self._view.ui.lbl_pred_analysis_mono_images,
6224                self._view.ui.cb_pred_analysis_mono_images,
6225                self._view.ui.btn_pred_analysis_mono_start,
6226            ]
6227            gui_utils.show_gui_elements(gui_elements_to_show)
6228            gui_utils.hide_gui_elements(gui_elements_to_hide)
6229            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6230                self._view.ui.btn_pred_analysis_mono_remove.show()
6231                self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6232                self._view.ui.btn_pred_analysis_mono_start.show()
6233                self._view.ui.lbl_pred_analysis_mono_images.show()
6234                self._view.ui.cb_pred_analysis_mono_images.show()
6235        else:
6236            # goes from analysis to prediction
6237            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6238                gui_elements_to_show = [
6239                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6240                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6241                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6242                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6243                ]
6244                gui_elements_to_hide = [
6245                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6246                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6247                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6248                    self._view.ui.txt_pred_analysis_mono_prot_name,
6249                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6250                    self._view.ui.btn_pred_analysis_mono_back,
6251                    self._view.ui.btn_pred_analysis_mono_next,
6252                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6253                    self._view.ui.txt_pred_analysis_mono_seq_name,
6254                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6255                    self._view.ui.btn_pred_analysis_mono_back_2,
6256                    self._view.ui.btn_pred_analysis_mono_add_protein,
6257                    self._view.ui.lbl_pred_mono_advanced_config_2,
6258                    self._view.ui.btn_pred_mono_advanced_config_2,
6259                ]
6260                gui_utils.show_gui_elements(gui_elements_to_show)
6261                gui_utils.hide_gui_elements(gui_elements_to_hide)
6262            else:
6263                gui_elements_to_show = [
6264                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6265                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6266                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6267                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6268                    self._view.ui.lbl_pred_mono_advanced_config_2,
6269                    self._view.ui.btn_pred_mono_advanced_config_2,
6270                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6271                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6272                ]
6273                gui_elements_to_hide = [
6274                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6275                    self._view.ui.txt_pred_analysis_mono_prot_name,
6276                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6277                    self._view.ui.btn_pred_analysis_mono_back,
6278                    self._view.ui.btn_pred_analysis_mono_next,
6279                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6280                    self._view.ui.txt_pred_analysis_mono_seq_name,
6281                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6282                    self._view.ui.btn_pred_analysis_mono_back_2,
6283                    self._view.ui.btn_pred_analysis_mono_add_protein,
6284                ]
6285                gui_utils.show_gui_elements(gui_elements_to_show)
6286                gui_utils.hide_gui_elements(gui_elements_to_hide)
6287                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
6288            self._view.ui.tabWidget.setTabEnabled(0, True)
6289            self._view.ui.tabWidget.setTabEnabled(1, False)
6290            self._view.ui.tabWidget.setCurrentIndex(0)
6291
6292    # </editor-fold>
6293
6294    # <editor-fold desc="Multimer prediction + analysis">
6295    def _init_multi_pred_analysis_page(self) -> None:
6296        """Clears the text boxes and sets the default values for the gui elements."""
6297        # <editor-fold desc="Prediction section">
6298        # clears everything
6299        self._view.ui.txt_pred_analysis_multi_prot_name.clear()
6300        self._view.ui.txt_pred_analysis_multi_prot_seq.clear()
6301        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clear()
6302        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1, -1, -1):
6303            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(i)
6304
6305        # sets up defaults: Prediction
6306        self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6307        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6308        self._view.ui.lbl_pred_analysis_multi_prot_name_status.setText("")
6309        self._view.ui.lbl_pred_analysis_multi_prot_seq_status.setText("")
6310
6311        # </editor-fold>
6312
6313        # <editor-fold desc="Analysis section">
6314        self._view.ui.list_pred_analysis_multi_overview.clear()
6315        self._view.ui.btn_pred_analysis_multi_remove.hide()
6316
6317        # </editor-fold>
6318
6319        # self.multi_pred_analysis_show_protein_overview()
6320
6321    def display_multimer_pred_analysis(self) -> None:
6322        """Displays the multimer prediction + analysis page."""
6323        # checks internet connection
6324        if not tools.check_internet_connectivity():
6325            gui_utils.no_internet_dialog()
6326            return
6327
6328        self._init_multi_pred_analysis_page()
6329        self._view.ui.table_pred_analysis_multi_prot_to_predict.clear()
6330        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6331            0,
6332            QtWidgets.QTableWidgetItem("Chain"),
6333        )
6334        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6335            1,
6336            QtWidgets.QTableWidgetItem("Sequence"),
6337        )
6338        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6339        gui_elements_to_show = [
6340            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6341            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6342            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6343        ]
6344        gui_elements_to_hide = [
6345            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6346            self._view.ui.lbl_pred_analysis_multi_prot_name,
6347            self._view.ui.txt_pred_analysis_multi_prot_name,
6348            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6349            self._view.ui.btn_pred_analysis_multi_back,
6350            self._view.ui.btn_pred_analysis_multi_next,
6351            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6352            self._view.ui.txt_pred_analysis_multi_prot_seq,
6353            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6354            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6355            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6356            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6357            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6358            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6359            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6360            self._view.ui.btn_pred_analysis_multi_back_2,
6361            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6362            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6363            self._view.ui.btn_pred_analysis_multi_advanced_config,
6364            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6365            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6366        ]
6367        gui_utils.show_gui_elements(gui_elements_to_show)
6368        gui_utils.hide_gui_elements(gui_elements_to_hide)
6369        if self._view.ui.tabWidget_2.currentIndex() == 1:
6370            self._view.ui.tabWidget_2.setCurrentIndex(0)
6371        self._view.ui.tabWidget_2.setTabEnabled(1, False)
6372        self._view.ui.tabWidget_2.setTabEnabled(0, True)
6373        tools.switch_page(
6374            self._view.ui.stackedWidget,
6375            self._view.ui.lbl_page_title,
6376            22,
6377            "Multimer Prediction + Analysis",
6378        )
6379        self.last_sidebar_button = styles.color_sidebar_buttons(
6380            self.last_sidebar_button,
6381            self._view.ui.btn_pred_analysis_multimer_page,
6382        )
6383        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEnabled(True)
6384
6385    # <editor-fold desc="Prediction section">
6386    def multi_pred_analysis_validate_protein_name(self) -> None:
6387        """Validates the input of the protein name in real-time."""
6388        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
6389            self._view.ui.txt_pred_analysis_multi_prot_name.text(),
6390            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6391        ):
6392            self._view.ui.lbl_pred_analysis_multi_prot_name_status.setText("Protein name already used.")
6393            self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6394            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6395        else:
6396            self._view.ui.btn_pred_analysis_multi_next.setEnabled(True)
6397            tools.validate_protein_name(
6398                self._view.ui.txt_pred_analysis_multi_prot_name,
6399                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6400                self._view.ui.btn_pred_analysis_multi_next,
6401            )
6402
6403    def multi_pred_analysis_validate_protein_sequence(self) -> None:
6404        """Validates the input of the protein sequence in real-time."""
6405        tools.validate_protein_sequence(
6406            self._view.ui.txt_pred_analysis_multi_prot_seq,
6407            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6408            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6409        )
6410
6411    def multi_pred_analysis_check_if_list_is_empty(self) -> None:
6412        """Checks if the list of sequences of the protein is empty."""
6413        if self._view.ui.list_pred_analysis_multi_prot_seq_overview.count() == 0:
6414            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6415        else:
6416            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(True)
6417
6418    def multi_pred_analysis_add_sequence_to_list(self) -> None:
6419        """Adds the entered sequence to the sequences of the protein."""
6420        self._view.ui.list_pred_analysis_multi_prot_seq_overview.addItem(
6421            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_seq.toPlainText()),
6422        )
6423        self.multi_pred_analysis_check_if_list_is_empty()
6424
6425    def multi_pred_analysis_remove_sequence_to_list(self) -> None:
6426        """Removes the entered sequence from the sequences of the protein."""
6427        self._view.ui.list_pred_analysis_multi_prot_seq_overview.takeItem(
6428            self._view.ui.list_pred_analysis_multi_prot_seq_overview.currentRow(),
6429        )
6430        self.multi_pred_analysis_check_if_list_is_empty()
6431        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)
6432
6433    def multi_pred_analysis_check_if_table_is_empty(self) -> None:
6434        """Checks if the list of proteins to predict is empty."""
6435        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 0:
6436            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
6437            gui_elements_to_show = [
6438                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6439                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6440                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6441            ]
6442            gui_elements_to_hide = [
6443                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6444                self._view.ui.lbl_pred_analysis_multi_prot_name,
6445                self._view.ui.txt_pred_analysis_multi_prot_name,
6446                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6447                self._view.ui.btn_pred_analysis_multi_back,
6448                self._view.ui.btn_pred_analysis_multi_next,
6449                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6450                self._view.ui.txt_pred_analysis_multi_prot_seq,
6451                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6452                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6453                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6454                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6455                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6456                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6457                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6458                self._view.ui.btn_pred_analysis_multi_back_2,
6459                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6460                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6461                self._view.ui.btn_pred_analysis_multi_advanced_config,
6462                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6463                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6464            ]
6465            gui_utils.show_gui_elements(gui_elements_to_show)
6466            gui_utils.hide_gui_elements(gui_elements_to_hide)
6467            self._view.ui.btn_pred_multi_predict.setEnabled(False)
6468            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
6469        else:
6470            self._view.ui.btn_pred_multi_predict.setEnabled(True)
6471            gui_elements_to_show = [
6472                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6473                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6474                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6475                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6476                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6477                self._view.ui.btn_pred_analysis_multi_advanced_config,
6478                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6479                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6480            ]
6481            gui_elements_to_hide = [
6482                self._view.ui.lbl_pred_analysis_multi_prot_name,
6483                self._view.ui.txt_pred_analysis_multi_prot_name,
6484                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6485                self._view.ui.btn_pred_analysis_multi_back,
6486                self._view.ui.btn_pred_analysis_multi_next,
6487                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6488                self._view.ui.txt_pred_analysis_multi_prot_seq,
6489                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6490                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6491                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6492                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6493                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6494                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6495                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6496                self._view.ui.btn_pred_analysis_multi_back_2,
6497                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6498            ]
6499            gui_utils.show_gui_elements(gui_elements_to_show)
6500            gui_utils.hide_gui_elements(gui_elements_to_hide)
6501            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
6502
6503    def multi_pred_analysis_add_protein_to_predict(self) -> None:
6504        """Adds the proteins to the list of proteins to predict."""
6505        for i in range(self._view.ui.list_pred_analysis_multi_prot_seq_overview.count()):
6506            self._view.ui.table_pred_analysis_multi_prot_to_predict.setRowCount(
6507                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6508            )
6509            self._view.ui.table_pred_analysis_multi_prot_to_predict.insertRow(
6510                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6511            )
6512            tmp_chain_seq = (
6513                constants.chain_dict.get(i),
6514                self._view.ui.list_pred_analysis_multi_prot_seq_overview.item(i).text(),
6515            )
6516            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6517                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6518                0,
6519                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
6520            )
6521            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6522                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6523                1,
6524                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
6525            )
6526            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_name.text())
6527            self._view.ui.table_pred_analysis_multi_prot_to_predict.setVerticalHeaderItem(
6528                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6529                name_item,
6530            )
6531        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6532        self.multi_pred_analysis_check_if_table_is_empty()
6533        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)
6534
6535    def multi_pred_analysis_remove_protein_to_predict(self) -> None:
6536        """Removes the selected protein from the list of proteins to predict."""
6537        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 1:
6538            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(0)
6539        else:
6540            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(
6541                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6542            )
6543            prot_name = self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(
6544                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6545            ).text()
6546            for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6547                if self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
6548                    self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6549                        i,
6550                        0,
6551                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
6552                    )
6553        self.multi_pred_analysis_check_if_table_is_empty()
6554        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)
6555
6556    def multi_pred_analysis_add(self) -> None:
6557        """Shows the gui elements for the protein name."""
6558        gui_elements_to_show = [
6559            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6560            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6561            self._view.ui.lbl_pred_analysis_multi_prot_name,
6562            self._view.ui.txt_pred_analysis_multi_prot_name,
6563            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6564            self._view.ui.btn_pred_analysis_multi_back,
6565            self._view.ui.btn_pred_analysis_multi_next,
6566        ]
6567        gui_elements_to_hide = [
6568            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6569            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6570            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6571            self._view.ui.txt_pred_analysis_multi_prot_seq,
6572            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6573            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6574            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6575            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6576            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6577            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6578            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6579            self._view.ui.btn_pred_analysis_multi_back_2,
6580            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6581            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6582            self._view.ui.btn_pred_analysis_multi_advanced_config,
6583            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6584            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6585        ]
6586        gui_utils.show_gui_elements(gui_elements_to_show)
6587        gui_utils.hide_gui_elements(gui_elements_to_hide)
6588        gui_utils.enable_text_box(
6589            self._view.ui.txt_pred_analysis_multi_prot_name,
6590            self._view.ui.lbl_pred_analysis_multi_prot_name,
6591        )
6592        gui_utils.disable_text_box(
6593            self._view.ui.txt_pred_analysis_multi_prot_seq,
6594            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6595        )
6596        self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6597        self._view.ui.txt_pred_analysis_multi_prot_name.clear()
6598        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6599        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() > 0:
6600            try:
6601                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentItem().setSelected(False)
6602            except AttributeError:
6603                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")
6604
6605    def multi_pred_analysis_back(self) -> None:
6606        """Hides the gui elements for the protein name."""
6607        gui_elements_to_show = [
6608            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6609            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6610            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6611        ]
6612        gui_elements_to_hide = [
6613            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6614            self._view.ui.lbl_pred_analysis_multi_prot_name,
6615            self._view.ui.txt_pred_analysis_multi_prot_name,
6616            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6617            self._view.ui.btn_pred_analysis_multi_back,
6618            self._view.ui.btn_pred_analysis_multi_next,
6619            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6620            self._view.ui.txt_pred_analysis_multi_prot_seq,
6621            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6622            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6623            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6624            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6625            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6626            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6627            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6628            self._view.ui.btn_pred_analysis_multi_back_2,
6629            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6630            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6631            self._view.ui.btn_pred_analysis_multi_advanced_config,
6632            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6633            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6634        ]
6635        gui_utils.show_gui_elements(gui_elements_to_show)
6636        gui_utils.hide_gui_elements(gui_elements_to_hide)
6637        self.multi_pred_analysis_check_if_table_is_empty()
6638
6639    def multi_pred_analysis_next(self) -> None:
6640        """Shows the gui elements for the protein sequence."""
6641        gui_elements_to_show = [
6642            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6643            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6644            self._view.ui.lbl_pred_analysis_multi_prot_name,
6645            self._view.ui.txt_pred_analysis_multi_prot_name,
6646            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6647            self._view.ui.txt_pred_analysis_multi_prot_seq,
6648            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6649            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6650            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6651            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6652            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6653            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6654            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6655            self._view.ui.btn_pred_analysis_multi_back_2,
6656            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6657        ]
6658        gui_elements_to_hide = [
6659            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6660            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6661            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6662            self._view.ui.btn_pred_analysis_multi_back,
6663            self._view.ui.btn_pred_analysis_multi_next,
6664            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6665            self._view.ui.btn_pred_analysis_multi_advanced_config,
6666            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6667            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6668        ]
6669        gui_utils.show_gui_elements(gui_elements_to_show)
6670        gui_utils.hide_gui_elements(gui_elements_to_hide)
6671        gui_utils.enable_text_box(
6672            self._view.ui.txt_pred_analysis_multi_prot_seq,
6673            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6674        )
6675        gui_utils.disable_text_box(
6676            self._view.ui.txt_pred_analysis_multi_prot_name,
6677            self._view.ui.lbl_pred_analysis_multi_prot_name,
6678        )
6679        self._view.ui.txt_pred_analysis_multi_prot_seq.clear()
6680        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clear()
6681        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6682        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)
6683        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2)
6684
6685    def multi_pred_analysis_back_2(self) -> None:
6686        """Hides the gui elements for the protein sequence."""
6687        gui_elements_to_show = [
6688            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6689            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6690            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6691            self._view.ui.btn_pred_analysis_multi_back,
6692            self._view.ui.btn_pred_analysis_multi_next,
6693            self._view.ui.lbl_pred_analysis_multi_prot_name,
6694            self._view.ui.txt_pred_analysis_multi_prot_name,
6695        ]
6696        gui_elements_to_hide = [
6697            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6698            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6699            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6700            self._view.ui.txt_pred_analysis_multi_prot_seq,
6701            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6702            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6703            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6704            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6705            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6706            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6707            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6708            self._view.ui.btn_pred_analysis_multi_back_2,
6709            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6710            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6711            self._view.ui.btn_pred_analysis_multi_advanced_config,
6712            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6713            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6714        ]
6715        gui_utils.show_gui_elements(gui_elements_to_show)
6716        gui_utils.hide_gui_elements(gui_elements_to_hide)
6717        gui_utils.enable_text_box(
6718            self._view.ui.txt_pred_analysis_multi_prot_name,
6719            self._view.ui.lbl_pred_analysis_multi_prot_name,
6720        )
6721        gui_utils.disable_text_box(
6722            self._view.ui.txt_pred_analysis_multi_prot_seq,
6723            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6724        )
6725
6726    def multi_pred_analysis_prot_seq_overview_item_changed(self) -> None:
6727        """Enables the remove button of the list of sequences of the protein."""
6728        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(True)
6729
6730    def multi_pred_analysis_prot_to_predict_item_changed(self) -> None:
6731        """Enables the remove button of the list of proteins to predict."""
6732        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(True)
6733
6734    # </editor-fold>
6735
6736    def switch_multimer_pred_analysis_tab(self) -> None:
6737        """Switches the tabs from prediction to analysis and vice versa."""
6738        if self._view.ui.tabWidget_2.currentIndex() == 0:
6739            # goes from prediction to analysis
6740            self._view.ui.tabWidget_2.setCurrentIndex(1)
6741            gui_elements_to_show = [
6742                self._view.ui.lbl_pred_analysis_multi_overview,
6743                self._view.ui.list_pred_analysis_multi_overview,
6744                self._view.ui.btn_pred_analysis_multi_add,
6745                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6746            ]
6747            gui_elements_to_hide = [
6748                self._view.ui.btn_pred_analysis_multi_remove,
6749                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6750                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6751                self._view.ui.lbl_analysis_batch_vs_3,
6752                self._view.ui.lbl_pred_analysis_multi_ref_chains,
6753                self._view.ui.list_pred_analysis_multi_ref_chains,
6754                self._view.ui.btn_pred_analysis_multi_back_4,
6755                self._view.ui.btn_pred_analysis_multi_next_3,
6756                self._view.ui.box_pred_analysis_multi_prot_struct_1,
6757                self._view.ui.box_pred_analysis_multi_prot_struct_2,
6758                self._view.ui.btn_pred_analysis_multi_back_3,
6759                self._view.ui.btn_pred_analysis_multi_next_2,
6760                self._view.ui.lbl_pred_analysis_multi_model_chains,
6761                self._view.ui.list_pred_analysis_multi_model_chains,
6762                self._view.ui.btn_pred_analysis_multi_back_5,
6763                self._view.ui.btn_pred_analysis_multi_next_4,
6764                self._view.ui.lbl_pred_analysis_multi_images,
6765                self._view.ui.cb_pred_analysis_multi_images,
6766                self._view.ui.btn_pred_analysis_multi_start,
6767            ]
6768            gui_utils.show_gui_elements(gui_elements_to_show)
6769            gui_utils.hide_gui_elements(gui_elements_to_hide)
6770            self._view.ui.tabWidget_2.setTabEnabled(1, True)
6771            self._view.ui.tabWidget_2.setTabEnabled(0, False)
6772            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6773                self._view.ui.btn_pred_analysis_multi_remove.show()
6774                self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6775                self._view.ui.btn_pred_analysis_multi_start.show()
6776                self._view.ui.lbl_pred_analysis_multi_images.show()
6777                self._view.ui.cb_pred_analysis_multi_images.show()
6778        else:
6779            # goes from analysis to prediction
6780            self._view.ui.tabWidget_2.setCurrentIndex(0)
6781            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6782                gui_elements_to_show = [
6783                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6784                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6785                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6786                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6787                ]
6788                gui_elements_to_hide = [
6789                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6790                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6791                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6792                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6793                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6794                    self._view.ui.txt_pred_analysis_multi_prot_name,
6795                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6796                    self._view.ui.btn_pred_analysis_multi_back,
6797                    self._view.ui.btn_pred_analysis_multi_next,
6798                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6799                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6800                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6801                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6802                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6803                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6804                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6805                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6806                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6807                    self._view.ui.btn_pred_analysis_multi_back_2,
6808                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6809                ]
6810                gui_utils.show_gui_elements(gui_elements_to_show)
6811                gui_utils.hide_gui_elements(gui_elements_to_hide)
6812            else:
6813                gui_elements_to_show = [
6814                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6815                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6816                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6817                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6818                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6819                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6820                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6821                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6822                ]
6823                gui_elements_to_hide = [
6824                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6825                    self._view.ui.txt_pred_analysis_multi_prot_name,
6826                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6827                    self._view.ui.btn_pred_analysis_multi_back,
6828                    self._view.ui.btn_pred_analysis_multi_next,
6829                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6830                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6831                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6832                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6833                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6834                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6835                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6836                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6837                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6838                    self._view.ui.btn_pred_analysis_multi_back_2,
6839                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6840                ]
6841                gui_utils.show_gui_elements(gui_elements_to_show)
6842                gui_utils.hide_gui_elements(gui_elements_to_hide)
6843            self._view.ui.tabWidget_2.setTabEnabled(0, True)
6844            self._view.ui.tabWidget_2.setTabEnabled(1, False)
6845
6846    # <editor-fold desc="Analysis section">
6847    def multi_pred_analysis_structure_analysis_add(self) -> None:
6848        """Shows the gui elements to choose the two proteins."""
6849        gui_elements_to_show = [
6850            self._view.ui.lbl_pred_analysis_multi_overview,
6851            self._view.ui.list_pred_analysis_multi_overview,
6852            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6853            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6854            self._view.ui.lbl_analysis_batch_vs_3,
6855            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6856            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6857            self._view.ui.btn_pred_analysis_multi_back_3,
6858            self._view.ui.btn_pred_analysis_multi_next_2,
6859        ]
6860        gui_elements_to_hide = [
6861            self._view.ui.btn_pred_analysis_multi_remove,
6862            self._view.ui.btn_pred_analysis_multi_add,
6863            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6864            self._view.ui.list_pred_analysis_multi_ref_chains,
6865            self._view.ui.btn_pred_analysis_multi_back_4,
6866            self._view.ui.btn_pred_analysis_multi_next_3,
6867            self._view.ui.lbl_pred_analysis_multi_model_chains,
6868            self._view.ui.list_pred_analysis_multi_model_chains,
6869            self._view.ui.btn_pred_analysis_multi_back_5,
6870            self._view.ui.btn_pred_analysis_multi_next_4,
6871            self._view.ui.lbl_pred_analysis_multi_images,
6872            self._view.ui.cb_pred_analysis_multi_images,
6873            self._view.ui.btn_pred_analysis_multi_start,
6874            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6875        ]
6876        gui_utils.show_gui_elements(gui_elements_to_show)
6877        gui_utils.hide_gui_elements(gui_elements_to_hide)
6878        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.clear()
6879        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.clear()
6880        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
6881        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")
6882        self.fill_multi_pred_analysis_protein_boxes()
6883        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6884            try:
6885                self._view.ui.list_pred_analysis_multi_overview.currentItem().setSelected(False)
6886            except AttributeError:
6887                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
6888
6889    def multi_pred_analysis_structure_analysis_back_3(self) -> None:
6890        """Hides the gui elements to choose the two proteins."""
6891        gui_elements_to_show = [
6892            self._view.ui.lbl_pred_analysis_multi_overview,
6893            self._view.ui.list_pred_analysis_multi_overview,
6894            self._view.ui.btn_pred_analysis_multi_add,
6895            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6896        ]
6897        gui_elements_to_hide = [
6898            self._view.ui.btn_pred_analysis_multi_remove,
6899            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6900            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6901            self._view.ui.lbl_analysis_batch_vs_3,
6902            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6903            self._view.ui.list_pred_analysis_multi_ref_chains,
6904            self._view.ui.btn_pred_analysis_multi_back_4,
6905            self._view.ui.btn_pred_analysis_multi_next_3,
6906            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6907            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6908            self._view.ui.btn_pred_analysis_multi_back_3,
6909            self._view.ui.btn_pred_analysis_multi_next_2,
6910            self._view.ui.lbl_pred_analysis_multi_model_chains,
6911            self._view.ui.list_pred_analysis_multi_model_chains,
6912            self._view.ui.btn_pred_analysis_multi_back_5,
6913            self._view.ui.btn_pred_analysis_multi_next_4,
6914            self._view.ui.lbl_pred_analysis_multi_images,
6915            self._view.ui.cb_pred_analysis_multi_images,
6916            self._view.ui.btn_pred_analysis_multi_start,
6917        ]
6918        gui_utils.show_gui_elements(gui_elements_to_show)
6919        gui_utils.hide_gui_elements(gui_elements_to_hide)
6920        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6921            self._view.ui.btn_pred_analysis_multi_remove.show()
6922            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6923            self._view.ui.btn_pred_analysis_multi_start.show()
6924            self._view.ui.lbl_pred_analysis_multi_images.show()
6925            self._view.ui.cb_pred_analysis_multi_images.show()
6926
6927    def multi_pred_analysis_structure_analysis_next_3(self) -> None:
6928        """Shows the gui elements to select the chains in protein 2."""
6929        gui_elements_to_show = [
6930            self._view.ui.lbl_pred_analysis_multi_overview,
6931            self._view.ui.list_pred_analysis_multi_overview,
6932            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6933            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6934            self._view.ui.lbl_analysis_batch_vs_3,
6935            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6936            self._view.ui.list_pred_analysis_multi_ref_chains,
6937            self._view.ui.lbl_pred_analysis_multi_model_chains,
6938            self._view.ui.list_pred_analysis_multi_model_chains,
6939            self._view.ui.btn_pred_analysis_multi_back_5,
6940            self._view.ui.btn_pred_analysis_multi_next_4,
6941        ]
6942        gui_elements_to_hide = [
6943            self._view.ui.btn_pred_analysis_multi_remove,
6944            self._view.ui.btn_pred_analysis_multi_add,
6945            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6946            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6947            self._view.ui.btn_pred_analysis_multi_back_3,
6948            self._view.ui.btn_pred_analysis_multi_next_2,
6949            self._view.ui.btn_pred_analysis_multi_back_4,
6950            self._view.ui.btn_pred_analysis_multi_next_3,
6951            self._view.ui.lbl_pred_analysis_multi_images,
6952            self._view.ui.cb_pred_analysis_multi_images,
6953            self._view.ui.btn_pred_analysis_multi_start,
6954            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6955        ]
6956        gui_utils.show_gui_elements(gui_elements_to_show)
6957        gui_utils.hide_gui_elements(gui_elements_to_hide)
6958        self._view.ui.list_pred_analysis_multi_model_chains.clear()
6959        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(False)
6960        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
6961
6962        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6963            if (
6964                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text()
6965                == self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText()
6966            ):
6967                self._view.ui.list_pred_analysis_multi_model_chains.addItem(
6968                    self._view.ui.table_pred_analysis_multi_prot_to_predict.item(i, 0).text(),
6969                )
6970        if self._view.ui.list_pred_analysis_multi_model_chains.count() == 0:
6971            tmp_protein = self._current_project.search_protein(
6972                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
6973            )
6974            for tmp_chain in tmp_protein.chains:
6975                if tmp_chain.chain_type == "protein_chain":
6976                    self._view.ui.list_pred_analysis_multi_model_chains.addItem(tmp_chain.chain_letter)
6977        if len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems()) == 1:
6978            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6979                f"Select 1 chain in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6980            )
6981        else:
6982            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6983                f"Select {len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())} chains in "
6984                f"protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6985            )
6986
6987    def multi_pred_analysis_structure_analysis_back_4(self) -> None:
6988        """Hides the gui elements to select the chains in protein 1."""
6989        gui_elements_to_show = [
6990            self._view.ui.lbl_pred_analysis_multi_overview,
6991            self._view.ui.list_pred_analysis_multi_overview,
6992            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6993            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6994            self._view.ui.lbl_analysis_batch_vs_3,
6995            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6996            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6997            self._view.ui.btn_pred_analysis_multi_back_3,
6998            self._view.ui.btn_pred_analysis_multi_next_2,
6999            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7000        ]
7001        gui_elements_to_hide = [
7002            self._view.ui.btn_pred_analysis_multi_remove,
7003            self._view.ui.btn_pred_analysis_multi_add,
7004            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7005            self._view.ui.list_pred_analysis_multi_ref_chains,
7006            self._view.ui.btn_pred_analysis_multi_back_4,
7007            self._view.ui.btn_pred_analysis_multi_next_3,
7008            self._view.ui.lbl_pred_analysis_multi_model_chains,
7009            self._view.ui.list_pred_analysis_multi_model_chains,
7010            self._view.ui.btn_pred_analysis_multi_back_5,
7011            self._view.ui.btn_pred_analysis_multi_next_4,
7012            self._view.ui.lbl_pred_analysis_multi_images,
7013            self._view.ui.cb_pred_analysis_multi_images,
7014            self._view.ui.btn_pred_analysis_multi_start,
7015        ]
7016        gui_utils.show_gui_elements(gui_elements_to_show)
7017        gui_utils.hide_gui_elements(gui_elements_to_hide)
7018        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
7019        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")
7020
7021    def multi_pred_analysis_structure_analysis_next_4(self) -> None:
7022        """Adds the protein pair to the list of protein pairs to analyze."""
7023        gui_elements_to_show = [
7024            self._view.ui.btn_pred_analysis_multi_remove,
7025            self._view.ui.btn_pred_analysis_multi_add,
7026            self._view.ui.lbl_pred_analysis_multi_overview,
7027            self._view.ui.list_pred_analysis_multi_overview,
7028            self._view.ui.lbl_pred_analysis_multi_images,
7029            self._view.ui.cb_pred_analysis_multi_images,
7030            self._view.ui.btn_pred_analysis_multi_start,
7031            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7032        ]
7033        gui_elements_to_hide = [
7034            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7035            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7036            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7037            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7038            self._view.ui.lbl_analysis_batch_vs_3,
7039            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7040            self._view.ui.list_pred_analysis_multi_ref_chains,
7041            self._view.ui.lbl_pred_analysis_multi_model_chains,
7042            self._view.ui.list_pred_analysis_multi_model_chains,
7043            self._view.ui.btn_pred_analysis_multi_back_3,
7044            self._view.ui.btn_pred_analysis_multi_next_2,
7045            self._view.ui.btn_pred_analysis_multi_back_4,
7046            self._view.ui.btn_pred_analysis_multi_next_3,
7047            self._view.ui.btn_pred_analysis_multi_back_5,
7048            self._view.ui.btn_pred_analysis_multi_next_4,
7049        ]
7050        gui_utils.show_gui_elements(gui_elements_to_show)
7051        gui_utils.hide_gui_elements(gui_elements_to_hide)
7052        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7053        prot_1_chains = []
7054        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7055            prot_1_chains.append(chain.text())
7056        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7057        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7058        prot_2_chains = []
7059        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7060            prot_2_chains.append(chain.text())
7061        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7062        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7063        item = QtWidgets.QListWidgetItem(analysis_name)
7064        self._view.ui.list_pred_analysis_multi_overview.addItem(item)
7065        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
7066
7067    def multi_pred_analysis_structure_analysis_back_5(self) -> None:
7068        """Hides the gui elements to select the chains in protein 2."""
7069        gui_elements_to_show = [
7070            self._view.ui.lbl_pred_analysis_multi_overview,
7071            self._view.ui.list_pred_analysis_multi_overview,
7072            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7073            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7074            self._view.ui.lbl_analysis_batch_vs_3,
7075            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7076            self._view.ui.list_pred_analysis_multi_ref_chains,
7077            self._view.ui.btn_pred_analysis_multi_back_4,
7078            self._view.ui.btn_pred_analysis_multi_next_3,
7079        ]
7080        gui_elements_to_hide = [
7081            self._view.ui.btn_pred_analysis_multi_remove,
7082            self._view.ui.btn_pred_analysis_multi_add,
7083            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7084            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7085            self._view.ui.btn_pred_analysis_multi_back_3,
7086            self._view.ui.btn_pred_analysis_multi_next_2,
7087            self._view.ui.btn_pred_analysis_multi_back_5,
7088            self._view.ui.btn_pred_analysis_multi_next_4,
7089            self._view.ui.lbl_pred_analysis_multi_images,
7090            self._view.ui.cb_pred_analysis_multi_images,
7091            self._view.ui.btn_pred_analysis_multi_start,
7092            self._view.ui.lbl_pred_analysis_multi_model_chains,
7093            self._view.ui.list_pred_analysis_multi_model_chains,
7094            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7095        ]
7096        gui_utils.show_gui_elements(gui_elements_to_show)
7097        gui_utils.hide_gui_elements(gui_elements_to_hide)
7098        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(True)
7099
7100        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText())
7101        # for tmp_chain in tmp_protein.chains:
7102        #     if tmp_chain.chain_type == "protein_chain":
7103        #         self._view.ui.list_pred_analysis_multi_ref_chains.addItem(tmp_chain.chain_letter)
7104
7105    def multi_pred_analysis_structure_analysis_overview_clicked(self) -> None:
7106        """Enables the remove button."""
7107        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(True)
7108
7109    def fill_multi_pred_analysis_protein_boxes(self) -> None:
7110        """Fills the combo boxes with the protein names."""
7111        protein_names = []
7112        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
7113            protein_names.append(self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text())
7114        for tmp_protein in self._current_project.proteins:
7115            protein_names.append(tmp_protein.get_molecule_object())
7116        protein_names.insert(0, "")
7117        protein_names = list(set(protein_names))
7118        self._view.ui.box_pred_analysis_multi_prot_struct_1.clear()
7119        self._view.ui.box_pred_analysis_multi_prot_struct_2.clear()
7120        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_1, protein_names)
7121        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_2, protein_names)
7122
7123    def remove_multi_pred_analysis_analysis_run(self) -> None:
7124        """Removes the selected protein pair from the list of protein pairs to analyze."""
7125        self._view.ui.list_pred_analysis_multi_overview.takeItem(
7126            self._view.ui.list_pred_analysis_multi_overview.currentRow(),
7127        )
7128        gui_elements_to_show = [
7129            self._view.ui.lbl_pred_analysis_multi_overview,
7130            self._view.ui.list_pred_analysis_multi_overview,
7131            self._view.ui.btn_pred_analysis_multi_add,
7132            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7133        ]
7134        gui_elements_to_hide = [
7135            self._view.ui.btn_pred_analysis_multi_remove,
7136            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7137            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7138            self._view.ui.lbl_analysis_batch_vs_3,
7139            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7140            self._view.ui.list_pred_analysis_multi_ref_chains,
7141            self._view.ui.btn_pred_analysis_multi_back_4,
7142            self._view.ui.btn_pred_analysis_multi_next_3,
7143            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7144            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7145            self._view.ui.btn_pred_analysis_multi_back_3,
7146            self._view.ui.btn_pred_analysis_multi_next_2,
7147            self._view.ui.lbl_pred_analysis_multi_model_chains,
7148            self._view.ui.list_pred_analysis_multi_model_chains,
7149            self._view.ui.btn_pred_analysis_multi_back_5,
7150            self._view.ui.btn_pred_analysis_multi_next_4,
7151            self._view.ui.lbl_pred_analysis_multi_images,
7152            self._view.ui.cb_pred_analysis_multi_images,
7153            self._view.ui.btn_pred_analysis_multi_start,
7154        ]
7155        gui_utils.show_gui_elements(gui_elements_to_show)
7156        gui_utils.hide_gui_elements(gui_elements_to_hide)
7157        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
7158            self._view.ui.btn_pred_analysis_multi_remove.show()
7159            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
7160            self._view.ui.btn_pred_analysis_multi_start.show()
7161            self._view.ui.lbl_pred_analysis_multi_images.show()
7162            self._view.ui.cb_pred_analysis_multi_images.show()
7163        # if self._view.ui.list_pred_analysis_multi_overview.count() == 0:
7164        #
7165        #     self._view.ui.btn_pred_analysis_multi_back_pred_setup.show()
7166        #     self._view.ui.btn_pred_analysis_multi_remove.hide()
7167
7168    def check_multi_pred_analysis_if_same_no_of_chains_selected(self) -> None:
7169        """Checks if the same number of chains were selected."""
7170        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7171        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_multi_model_chains.selectedItems()):
7172            self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(True)
7173
7174        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7175        prot_1_chains = []
7176        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7177            prot_1_chains.append(chain.text())
7178        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7179        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7180        prot_2_chains = []
7181        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7182            prot_2_chains.append(chain.text())
7183        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7184        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7185        for tmp_row in range(self._view.ui.list_pred_analysis_multi_overview.count()):
7186            if analysis_name == self._view.ui.list_pred_analysis_multi_overview.item(tmp_row).text():
7187                self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7188                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next_4)
7189                return
7190
7191    def check_multi_pred_analysis_if_prot_structs_are_filled(self) -> None:
7192        """Checks if two proteins were selected."""
7193        prot_1 = self._view.ui.box_pred_analysis_multi_prot_struct_1.itemText(
7194            self._view.ui.box_pred_analysis_multi_prot_struct_1.currentIndex(),
7195        )
7196        prot_2 = self._view.ui.box_pred_analysis_multi_prot_struct_2.itemText(
7197            self._view.ui.box_pred_analysis_multi_prot_struct_2.currentIndex(),
7198        )
7199        if prot_1 != "" and prot_2 != "":
7200            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(True)
7201        else:
7202            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(False)
7203
7204    def count_multi_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
7205        """Counts the number of chains in protein 1."""
7206        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())
7207        if self.no_of_selected_chains > 0:
7208            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(True)
7209        else:
7210            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(False)
7211
7212    # </editor-fold>
7213    # </editor-fold>
7214
7215    # <editor-fold desc="Distance analysis">
7216    def structure_analysis_add(self) -> None:
7217        """Shows the gui elements to choose the two proteins."""
7218        gui_elements_to_show = [
7219            self._view.ui.lbl_analysis_batch_overview,
7220            self._view.ui.list_analysis_batch_overview,
7221            self._view.ui.lbl_analysis_batch_prot_struct_1,
7222            self._view.ui.box_analysis_batch_prot_struct_1,
7223            self._view.ui.lbl_analysis_batch_vs,
7224            self._view.ui.lbl_analysis_batch_prot_struct_2,
7225            self._view.ui.box_analysis_batch_prot_struct_2,
7226            self._view.ui.btn_analysis_batch_back,
7227            self._view.ui.btn_analysis_batch_next,
7228        ]
7229        gui_elements_to_hide = [
7230            self._view.ui.btn_analysis_batch_remove,
7231            self._view.ui.btn_analysis_batch_add,
7232            self._view.ui.lbl_analysis_batch_ref_chains,
7233            self._view.ui.list_analysis_batch_ref_chains,
7234            self._view.ui.btn_analysis_batch_back_2,
7235            self._view.ui.btn_analysis_batch_next_2,
7236            self._view.ui.lbl_analysis_batch_model_chains,
7237            self._view.ui.list_analysis_batch_model_chains,
7238            self._view.ui.btn_analysis_batch_back_3,
7239            self._view.ui.btn_analysis_batch_next_3,
7240            self._view.ui.lbl_analysis_batch_images,
7241            self._view.ui.cb_analysis_batch_images,
7242            self._view.ui.btn_analysis_batch_start,
7243        ]
7244
7245        gui_utils.show_gui_elements(gui_elements_to_show)
7246        gui_utils.hide_gui_elements(gui_elements_to_hide)
7247        self._view.ui.lbl_analysis_batch_prot_struct_1.clear()
7248        self._view.ui.lbl_analysis_batch_prot_struct_2.clear()
7249        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7250        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")
7251        self.fill_protein_boxes_batch()
7252        if self._view.ui.list_analysis_batch_overview.count() > 0:
7253            try:
7254                self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7255            except AttributeError:
7256                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
7257
7258    def structure_analysis_back(self) -> None:
7259        """Hides the gui elements to choose the two proteins."""
7260        gui_elements_to_show = [
7261            self._view.ui.lbl_analysis_batch_overview,
7262            self._view.ui.list_analysis_batch_overview,
7263            self._view.ui.btn_analysis_batch_add,
7264        ]
7265        gui_elements_to_hide = [
7266            self._view.ui.btn_analysis_batch_remove,
7267            self._view.ui.lbl_analysis_batch_prot_struct_1,
7268            self._view.ui.lbl_analysis_batch_prot_struct_2,
7269            self._view.ui.lbl_analysis_batch_vs,
7270            self._view.ui.lbl_analysis_batch_ref_chains,
7271            self._view.ui.list_analysis_batch_ref_chains,
7272            self._view.ui.btn_analysis_batch_back_2,
7273            self._view.ui.btn_analysis_batch_next_2,
7274            self._view.ui.box_analysis_batch_prot_struct_1,
7275            self._view.ui.box_analysis_batch_prot_struct_2,
7276            self._view.ui.btn_analysis_batch_back,
7277            self._view.ui.btn_analysis_batch_next,
7278            self._view.ui.lbl_analysis_batch_model_chains,
7279            self._view.ui.list_analysis_batch_model_chains,
7280            self._view.ui.btn_analysis_batch_back_3,
7281            self._view.ui.btn_analysis_batch_next_3,
7282            self._view.ui.lbl_analysis_batch_images,
7283            self._view.ui.cb_analysis_batch_images,
7284            self._view.ui.btn_analysis_batch_start,
7285        ]
7286        gui_utils.show_gui_elements(gui_elements_to_show)
7287        gui_utils.hide_gui_elements(gui_elements_to_hide)
7288        if self._view.ui.list_analysis_batch_overview.count() > 0:
7289            self._view.ui.btn_analysis_batch_remove.show()
7290            self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7291            self._view.ui.btn_analysis_batch_start.show()
7292            self._view.ui.lbl_analysis_batch_images.show()
7293            self._view.ui.cb_analysis_batch_images.show()
7294
7295    def structure_analysis_next_2(self) -> None:
7296        """Shows the gui elements to select the chains in protein 2."""
7297        gui_elements_to_show = [
7298            self._view.ui.lbl_analysis_batch_overview,
7299            self._view.ui.list_analysis_batch_overview,
7300            self._view.ui.lbl_analysis_batch_prot_struct_1,
7301            self._view.ui.lbl_analysis_batch_prot_struct_2,
7302            self._view.ui.lbl_analysis_batch_vs,
7303            self._view.ui.lbl_analysis_batch_ref_chains,
7304            self._view.ui.list_analysis_batch_ref_chains,
7305            self._view.ui.lbl_analysis_batch_model_chains,
7306            self._view.ui.list_analysis_batch_model_chains,
7307            self._view.ui.btn_analysis_batch_back_3,
7308            self._view.ui.btn_analysis_batch_next_3,
7309        ]
7310        gui_elements_to_hide = [
7311            self._view.ui.btn_analysis_batch_remove,
7312            self._view.ui.btn_analysis_batch_add,
7313            self._view.ui.box_analysis_batch_prot_struct_1,
7314            self._view.ui.box_analysis_batch_prot_struct_2,
7315            self._view.ui.btn_analysis_batch_back,
7316            self._view.ui.btn_analysis_batch_next,
7317            self._view.ui.btn_analysis_batch_back_2,
7318            self._view.ui.btn_analysis_batch_next_2,
7319            self._view.ui.lbl_analysis_batch_images,
7320            self._view.ui.cb_analysis_batch_images,
7321            self._view.ui.btn_analysis_batch_start,
7322        ]
7323        gui_utils.show_gui_elements(gui_elements_to_show)
7324        gui_utils.hide_gui_elements(gui_elements_to_hide)
7325        self._view.ui.list_analysis_batch_model_chains.clear()
7326        self._view.ui.list_analysis_batch_ref_chains.setEnabled(False)
7327        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7328
7329        tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7330        for tmp_chain in tmp_protein.chains:
7331            if tmp_chain.chain_type == "protein_chain":
7332                self._view.ui.list_analysis_batch_model_chains.addItem(tmp_chain.chain_letter)
7333        if len(self._view.ui.list_analysis_batch_ref_chains.selectedItems()) == 1:
7334            self._view.ui.lbl_analysis_batch_model_chains.setText(
7335                f"Select 1 chain in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7336            )
7337        else:
7338            self._view.ui.lbl_analysis_batch_model_chains.setText(
7339                f"Select {len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())} chains in "
7340                f"protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7341            )
7342
7343    def structure_analysis_back_2(self) -> None:
7344        """Hides the gui elements to select the chains in protein 1."""
7345        gui_elements_to_show = [
7346            self._view.ui.lbl_analysis_batch_overview,
7347            self._view.ui.list_analysis_batch_overview,
7348            self._view.ui.lbl_analysis_batch_prot_struct_1,
7349            self._view.ui.box_analysis_batch_prot_struct_1,
7350            self._view.ui.lbl_analysis_batch_vs,
7351            self._view.ui.lbl_analysis_batch_prot_struct_2,
7352            self._view.ui.box_analysis_batch_prot_struct_2,
7353            self._view.ui.btn_analysis_batch_back,
7354            self._view.ui.btn_analysis_batch_next,
7355        ]
7356        gui_elements_to_hide = [
7357            self._view.ui.btn_analysis_batch_remove,
7358            self._view.ui.btn_analysis_batch_add,
7359            self._view.ui.lbl_analysis_batch_ref_chains,
7360            self._view.ui.list_analysis_batch_ref_chains,
7361            self._view.ui.btn_analysis_batch_back_2,
7362            self._view.ui.btn_analysis_batch_next_2,
7363            self._view.ui.lbl_analysis_batch_model_chains,
7364            self._view.ui.list_analysis_batch_model_chains,
7365            self._view.ui.btn_analysis_batch_back_3,
7366            self._view.ui.btn_analysis_batch_next_3,
7367            self._view.ui.lbl_analysis_batch_images,
7368            self._view.ui.cb_analysis_batch_images,
7369            self._view.ui.btn_analysis_batch_start,
7370        ]
7371        gui_utils.show_gui_elements(gui_elements_to_show)
7372        gui_utils.hide_gui_elements(gui_elements_to_hide)
7373        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7374        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")
7375
7376    def structure_analysis_next_3(self) -> None:
7377        """Adds the protein pair to the list of protein pairs to analyze."""
7378        gui_elements_to_show = [
7379            self._view.ui.btn_analysis_batch_remove,
7380            self._view.ui.btn_analysis_batch_add,
7381            self._view.ui.lbl_analysis_batch_overview,
7382            self._view.ui.list_analysis_batch_overview,
7383            self._view.ui.lbl_analysis_batch_images,
7384            self._view.ui.cb_analysis_batch_images,
7385            self._view.ui.btn_analysis_batch_start,
7386        ]
7387        gui_elements_to_hide = [
7388            self._view.ui.box_analysis_batch_prot_struct_1,
7389            self._view.ui.box_analysis_batch_prot_struct_2,
7390            self._view.ui.lbl_analysis_batch_prot_struct_1,
7391            self._view.ui.lbl_analysis_batch_prot_struct_2,
7392            self._view.ui.lbl_analysis_batch_vs,
7393            self._view.ui.lbl_analysis_batch_ref_chains,
7394            self._view.ui.list_analysis_batch_ref_chains,
7395            self._view.ui.lbl_analysis_batch_model_chains,
7396            self._view.ui.list_analysis_batch_model_chains,
7397            self._view.ui.btn_analysis_batch_back,
7398            self._view.ui.btn_analysis_batch_next,
7399            self._view.ui.btn_analysis_batch_back_2,
7400            self._view.ui.btn_analysis_batch_next_2,
7401            self._view.ui.btn_analysis_batch_back_3,
7402            self._view.ui.btn_analysis_batch_next_3,
7403        ]
7404        gui_utils.show_gui_elements(gui_elements_to_show)
7405        gui_utils.hide_gui_elements(gui_elements_to_hide)
7406        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7407        prot_1_chains = []
7408        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7409            prot_1_chains.append(chain.text())
7410        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7411        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7412        prot_2_chains = []
7413        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7414            prot_2_chains.append(chain.text())
7415        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7416        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7417        item = QtWidgets.QListWidgetItem(analysis_name)
7418        self._view.ui.list_analysis_batch_overview.addItem(item)
7419        self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7420
7421    def structure_analysis_back_3(self) -> None:
7422        """Hides the gui elements to select the chains in protein 2."""
7423        gui_elements_to_show = [
7424            self._view.ui.lbl_analysis_batch_overview,
7425            self._view.ui.list_analysis_batch_overview,
7426            self._view.ui.lbl_analysis_batch_prot_struct_1,
7427            self._view.ui.lbl_analysis_batch_prot_struct_2,
7428            self._view.ui.lbl_analysis_batch_vs,
7429            self._view.ui.lbl_analysis_batch_ref_chains,
7430            self._view.ui.list_analysis_batch_ref_chains,
7431            self._view.ui.btn_analysis_batch_back_2,
7432            self._view.ui.btn_analysis_batch_next_2,
7433        ]
7434        gui_elements_to_hide = [
7435            self._view.ui.btn_analysis_batch_remove,
7436            self._view.ui.btn_analysis_batch_add,
7437            self._view.ui.box_analysis_batch_prot_struct_1,
7438            self._view.ui.box_analysis_batch_prot_struct_2,
7439            self._view.ui.btn_analysis_batch_back,
7440            self._view.ui.btn_analysis_batch_next,
7441            self._view.ui.btn_analysis_batch_back_3,
7442            self._view.ui.btn_analysis_batch_next_3,
7443            self._view.ui.lbl_analysis_batch_images,
7444            self._view.ui.cb_analysis_batch_images,
7445            self._view.ui.btn_analysis_batch_start,
7446            self._view.ui.lbl_analysis_batch_model_chains,
7447            self._view.ui.list_analysis_batch_model_chains,
7448        ]
7449        gui_utils.show_gui_elements(gui_elements_to_show)
7450        gui_utils.hide_gui_elements(gui_elements_to_hide)
7451        self._view.ui.list_analysis_batch_ref_chains.setEnabled(True)
7452
7453        # tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7454        # for tmp_chain in tmp_protein.chains:
7455        #     if tmp_chain.chain_type == "protein_chain":
7456        #         self._view.ui.list_analysis_batch_ref_chains.addItem(tmp_chain.chain_letter)
7457
7458    def structure_analysis_overview_clicked(self) -> None:
7459        """Enables the remove button."""
7460        self._view.ui.btn_analysis_batch_remove.setEnabled(True)
7461
7462    def fill_protein_boxes_batch(self) -> None:
7463        """Fills the combo boxes with the protein names."""
7464        proteins = []
7465        for tmp_protein in self._current_project.proteins:
7466            proteins.append(tmp_protein.get_molecule_object())
7467        proteins.insert(0, "")
7468        self._view.ui.box_analysis_batch_prot_struct_1.clear()
7469        self._view.ui.box_analysis_batch_prot_struct_2.clear()
7470        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_1, proteins)
7471        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_2, proteins)
7472
7473    def remove_analysis_run(self) -> None:
7474        """Removes the selected protein pair from the list of protein pairs to analyze."""
7475        self._view.ui.list_analysis_batch_overview.takeItem(self._view.ui.list_analysis_batch_overview.currentRow())
7476        if self._view.ui.list_analysis_batch_overview.count() == 0:
7477            gui_elements_to_show = [
7478                self._view.ui.lbl_analysis_batch_overview,
7479                self._view.ui.list_analysis_batch_overview,
7480                self._view.ui.btn_analysis_batch_add,
7481            ]
7482
7483            gui_elements_to_hide = [
7484                self._view.ui.btn_analysis_batch_remove,
7485                self._view.ui.lbl_analysis_batch_prot_struct_1,
7486                self._view.ui.lbl_analysis_batch_prot_struct_2,
7487                self._view.ui.lbl_analysis_batch_vs,
7488                self._view.ui.lbl_analysis_batch_ref_chains,
7489                self._view.ui.list_analysis_batch_ref_chains,
7490                self._view.ui.btn_analysis_batch_back_2,
7491                self._view.ui.btn_analysis_batch_next_2,
7492                self._view.ui.box_analysis_batch_prot_struct_1,
7493                self._view.ui.box_analysis_batch_prot_struct_2,
7494                self._view.ui.btn_analysis_batch_back,
7495                self._view.ui.btn_analysis_batch_next,
7496                self._view.ui.lbl_analysis_batch_model_chains,
7497                self._view.ui.list_analysis_batch_model_chains,
7498                self._view.ui.btn_analysis_batch_back_3,
7499                self._view.ui.btn_analysis_batch_next_3,
7500                self._view.ui.lbl_analysis_batch_images,
7501                self._view.ui.cb_analysis_batch_images,
7502                self._view.ui.btn_analysis_batch_start,
7503            ]
7504
7505            gui_utils.show_gui_elements(gui_elements_to_show)
7506            gui_utils.hide_gui_elements(gui_elements_to_hide)
7507            self._view.ui.btn_analysis_batch_remove.hide()
7508        else:
7509            if self._view.ui.list_analysis_batch_overview.count() > 0:
7510                try:
7511                    self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7512                except AttributeError:
7513                    constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
7514        self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7515
7516    def check_if_same_no_of_chains_selected_batch(self) -> None:
7517        """Checks if the same number of proteins were selected."""
7518        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7519        if self.no_of_selected_chains == len(self._view.ui.list_analysis_batch_model_chains.selectedItems()):
7520            self._view.ui.btn_analysis_batch_next_3.setEnabled(True)
7521
7522        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7523        prot_1_chains = []
7524        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7525            prot_1_chains.append(chain.text())
7526        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7527        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7528        prot_2_chains = []
7529        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7530            prot_2_chains.append(chain.text())
7531        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7532        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7533        for tmp_row in range(self._view.ui.list_analysis_batch_overview.count()):
7534            if analysis_name == self._view.ui.list_analysis_batch_overview.item(tmp_row).text():
7535                self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7536                styles.color_button_not_ready(self._view.ui.btn_analysis_batch_next_3)
7537                return
7538
7539    def check_if_prot_structs_are_filled_batch(self) -> None:
7540        """Checks if two proteins were selected."""
7541        prot_1 = self._view.ui.box_analysis_batch_prot_struct_1.itemText(
7542            self._view.ui.box_analysis_batch_prot_struct_1.currentIndex(),
7543        )
7544        prot_2 = self._view.ui.box_analysis_batch_prot_struct_2.itemText(
7545            self._view.ui.box_analysis_batch_prot_struct_2.currentIndex(),
7546        )
7547        if prot_1 != "" and prot_2 != "":
7548            self._view.ui.btn_analysis_batch_next.setEnabled(True)
7549        else:
7550            self._view.ui.btn_analysis_batch_next.setEnabled(False)
7551
7552    def count_batch_selected_chains_for_prot_struct_1(self) -> None:
7553        """Counts the number of chains of protein 1."""
7554        self.no_of_selected_chains = len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())
7555        if self.no_of_selected_chains > 0:
7556            self._view.ui.btn_analysis_batch_next_2.setEnabled(True)
7557        else:
7558            self._view.ui.btn_analysis_batch_next_2.setEnabled(False)
7559
7560    # </editor-fold>
7561
7562    # <editor-fold desc="Analysis images">
7563    def display_image_analysis_page(self) -> None:
7564        """Displays the analysis image work area."""
7565        # get all protein pairs without images
7566        self._view.ui.list_analysis_images_struct_analysis.clear()
7567        self._view.ui.list_analysis_images_creation_struct_analysis.clear()
7568        for tmp_protein_pair in self._current_project.protein_pairs:
7569            if len(tmp_protein_pair.distance_analysis.analysis_results.structure_aln_image) == 0:
7570                self._view.ui.list_analysis_images_struct_analysis.addItem(tmp_protein_pair.name)
7571        self.last_sidebar_button = styles.color_sidebar_buttons(
7572            self.last_sidebar_button,
7573            self._view.ui.btn_image_analysis_page,
7574        )
7575        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 23, "Analysis Images")
7576        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7577        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7578        self._view.ui.btn_start_automatic_image_creation.setEnabled(False)
7579
7580    def analysis_images_enable_add(self) -> None:
7581        """Enables the add button."""
7582        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(True)
7583
7584    def analysis_images_enable_remove(self) -> None:
7585        """Enables the remove button."""
7586        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(True)
7587
7588    def add_protein_pair_to_image_creation_queue(self) -> None:
7589        """Adds a protein pair from the list of protein pairs to make images of."""
7590        protein_pair_to_add = self._view.ui.list_analysis_images_struct_analysis.currentItem().text()
7591        self._view.ui.list_analysis_images_creation_struct_analysis.addItem(protein_pair_to_add)
7592        self._view.ui.list_analysis_images_struct_analysis.takeItem(
7593            self._view.ui.list_analysis_images_struct_analysis.currentRow(),
7594        )
7595        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7596        self.analysis_images_check_if_creation_can_start()
7597
7598    def remove_protein_pair_from_image_creation_queue(self) -> None:
7599        """Removes a protein pair from the list of protein pairs to make images of."""
7600        protein_pair_to_remove = self._view.ui.list_analysis_images_creation_struct_analysis.currentItem()
7601        self._view.ui.list_analysis_images_creation_struct_analysis.takeItem(
7602            self._view.ui.list_analysis_images_creation_struct_analysis.currentRow(),
7603        )
7604        self._view.ui.list_analysis_images_struct_analysis.addItem(protein_pair_to_remove)
7605        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7606        self.analysis_images_check_if_creation_can_start()
7607
7608    def analysis_images_check_if_creation_can_start(self) -> None:
7609        """Checks if the list of protein pairs which get images are empty."""
7610        if self._view.ui.list_analysis_images_creation_struct_analysis.count() > 0:
7611            self._view.ui.btn_start_automatic_image_creation.setEnabled(True)
7612        else:
7613            self._view.ui.btn_start_automatic_image_creation.setEnabled(False)
7614
7615    # </editor-fold>
7616
7617    # </editor-fold>
7618
7619    def update_status(self, message: str) -> None:
7620        """Updates the status bar of the main view with a custom message."""
7621        self._view.status_bar.showMessage(message)
logger = <Logger C:\Users\martin\github_repos\PySSA\pyssa\presenter\main_presenter.py (DEBUG)>
class MainPresenter:
  90class MainPresenter:
  91    """Class for main presenter of the pyssa plugin."""
  92
  93    """
  94    The main view of the pyssa plugin.
  95    """
  96    _view: "main_view.MainView"
  97
  98    """
  99    The path to the active workspace.
 100    """
 101    _workspace_path: pathlib.Path
 102
 103    """
 104    The application settings object.
 105    """
 106    _application_settings: "settings.Settings"
 107
 108    """
 109    The currently active project.
 110    """
 111    _current_project: "project.Project"
 112
 113    """
 114    A watcher for the project state.
 115    """
 116    _project_watcher: "project_watcher.ProjectWatcher"
 117
 118    """
 119    The active task of the application.
 120    """
 121    _active_task: tasks.Task
 122
 123    def __init__(self, a_view: "main_view.MainView") -> None:
 124        """Constructor.
 125
 126        Args:
 127            a_view: the main view of the pyssa plugin.
 128
 129        Raises:
 130            IllegalArgumentException: If an argument is illegal.
 131        """
 132        # <editor-fold desc="Checks">
 133        safeguard.Safeguard.check_if_value_is_not_none(a_view, logger)
 134
 135        # </editor-fold>
 136
 137        # <editor-fold desc="Initialize class attributes">
 138        self._view = a_view
 139        self._workspace_path = constants.DEFAULT_WORKSPACE_PATH
 140        # TODO: settings and project objects get not initialized properly
 141        self._application_settings = settings.Settings("", "")
 142        self._current_project: "project.Project" = project.Project()
 143        self._project_watcher: "project_watcher.ProjectWatcher" = project_watcher.ProjectWatcher(self._current_project)
 144
 145        # </editor-fold>
 146
 147        # Check OS
 148        main_window_util.check_operating_system()
 149        # Create log dir
 150        # <editor-fold desc="Program directory check">
 151        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa"))
 152        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa/logs"))
 153        constants.PYSSA_LOGGER.info("Checked program and logs directory.")
 154
 155        # </editor-fold>
 156        # Configure settings
 157        # <editor-fold desc="Setup App Settings">
 158        self._application_settings = settings.Settings(constants.SETTINGS_DIR, constants.SETTINGS_FILENAME)
 159        if not os.path.exists(constants.SETTINGS_FULL_FILEPATH):
 160            constants.PYSSA_LOGGER.info("Settings file not found, open configuration dialog.")
 161            # Configuration dialog to setup setting file
 162            dialog = dialog_startup.DialogStartup()
 163            dialog.exec_()
 164
 165            # checks if the cancel button was pressed
 166            if dialog_startup.global_var_terminate_app == 1:
 167                os.remove(constants.SETTINGS_FULL_FILEPATH)
 168                constants.PYSSA_LOGGER.info("Configuration dialog closed, and removed new settings file.")
 169                sys.exit()
 170
 171            self._application_settings.app_launch = 1
 172            self._application_settings.workspace_path = pathlib.Path(dialog_startup.global_var_startup_workspace)
 173
 174            constants.PYSSA_LOGGER.info("Demo projects are getting downloaded and extracted ...")
 175            import zipfile
 176
 177            with zipfile.ZipFile(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"), "r") as zip_ref:
 178                zip_ref.extractall(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects"))
 179            constants.PYSSA_LOGGER.info(
 180                "Demo projects are downloaded and extracted.\n Import of demo projects started ...",
 181            )
 182
 183            path_of_demo_projects = pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects")
 184            tmp_project = project.Project("", dialog_startup.global_var_startup_workspace)
 185            for tmp_filename in os.listdir(path_of_demo_projects):
 186                try:
 187                    tmp_project = tmp_project.deserialize_project(
 188                        pathlib.Path(f"{path_of_demo_projects}/{tmp_filename}"),
 189                        self._application_settings,
 190                    )
 191                except exception.IllegalArgumentError:
 192                    constants.PYSSA_LOGGER.warning(
 193                        "The workspace path does not exist on this system, " "but this is due to the demo projects.",
 194                    )
 195                tmp_project.set_workspace_path(dialog_startup.global_var_startup_workspace)
 196                new_filepath = pathlib.Path(f"{dialog_startup.global_var_startup_workspace}/{tmp_filename}")
 197                tmp_project.serialize_project(new_filepath)
 198            constants.PYSSA_LOGGER.info("Import process of demo projects finished.")
 199            try:
 200                os.remove(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"))
 201            except FileNotFoundError:
 202                constants.PYSSA_LOGGER.warning("Zip archive of demo projects could not be found!")
 203            constants.PYSSA_LOGGER.info("Serialize settings ...")
 204            self._application_settings.serialize_settings()
 205            constants.PYSSA_LOGGER.info("Serialize settings finished.")
 206
 207            QtWidgets.QApplication.restoreOverrideCursor()
 208
 209        globals.g_settings = main_window_util.setup_app_settings(self._application_settings)
 210        self._application_settings = globals.g_settings
 211        # </editor-fold>
 212        # Check version number
 213        main_window_util.check_version_number()
 214
 215        # <editor-fold desc="Class attributes">
 216        self._workspace_path = self._application_settings.workspace_path
 217        self._workspace_status = f"Current workspace: {str(self._workspace_path)}"
 218        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
 219        self.prediction_configuration = prediction_configuration.PredictionConfiguration(True, "pdb70")
 220        self.results_name = ""
 221        self.no_of_selected_chains = 0
 222        self.plot_dialog = QtWidgets.QDialog(self._view)
 223        self.view_box = None
 224        self.block_box_expert_install = basic_boxes.no_buttons(
 225            "Local Colabfold installation",
 226            "An installation process is currently running.",
 227            QtWidgets.QMessageBox.Information,
 228        )
 229        self.prediction_type = 0
 230        self.current_session = current_session.CurrentSession("", "", "")
 231        self.is_distance_plot_open = False
 232        self.distance_plot_dialog = None
 233
 234        self.main_window_state = main_window_state.MainWindowState(
 235            results_state.ResultsState(),
 236            image_state.ImageState(),
 237        )
 238
 239        constants.PYSSA_LOGGER.info("Setup class attributes finished.")
 240        # </editor-fold>
 241
 242        # sets up the status bar
 243        self._setup_statusbar()
 244        tools.create_directory(constants.SETTINGS_DIR, "scratch")
 245        self._setup_default_configuration()
 246
 247        # if len(os.listdir(constants.LOG_PATH)) > 0:
 248        #     self.open_change_log()
 249
 250        constants.PYSSA_LOGGER.info("Setup rest of GUI related elements ...")
 251
 252        # <editor-fold desc="GUI page management">
 253        # -- Gui page management vars
 254        self.batch_analysis_management: gui_page_management.GuiPageManagement
 255        self.results_management: gui_page_management.GuiPageManagement
 256
 257        # management functions
 258        self._create_batch_analysis_management()
 259        self._create_results_management()
 260
 261        # </editor-fold>
 262
 263        # <editor-fold desc="Block box definitions">
 264        self.block_box_analysis = basic_boxes.no_buttons(
 265            "Analysis",
 266            "An analysis is currently running, please wait.",
 267            QtWidgets.QMessageBox.Information,
 268        )
 269        self.block_box_prediction: QtWidgets.QMessageBox = QtWidgets.QMessageBox()
 270        self.block_box_images = basic_boxes.no_buttons(
 271            "Analysis Images",
 272            "Images getting created, please wait.",
 273            QtWidgets.QMessageBox.Information,
 274        )
 275        self.block_box_uni = basic_boxes.no_buttons("Generic", "Generic", QtWidgets.QMessageBox.Information)
 276
 277        # </editor-fold>
 278
 279        # configure gui element properties
 280        self._view.ui.txt_results_aligned_residues.setAlignment(QtCore.Qt.AlignRight)
 281        self._view.ui.table_pred_mono_prot_to_predict.setSizeAdjustPolicy(
 282            QtWidgets.QAbstractScrollArea.AdjustToContents,
 283        )
 284        self._view.ui.table_pred_mono_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
 285        self._view.ui.table_pred_multi_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
 286        self._view.ui.list_pred_analysis_multi_ref_chains.setSelectionMode(
 287            QtWidgets.QAbstractItemView.ExtendedSelection,
 288        )
 289        self._view.ui.list_pred_analysis_multi_model_chains.setSelectionMode(
 290            QtWidgets.QAbstractItemView.ExtendedSelection,
 291        )
 292
 293        # helper attributes
 294        self.pymol_session_specs = {
 295            pyssa_keys.SESSION_SPEC_PROTEIN: [0, ""],
 296            pyssa_keys.SESSION_SPEC_COLOR: [0, ""],
 297            pyssa_keys.SESSION_SPEC_REPRESENTATION: [0, ""],
 298            pyssa_keys.SESSION_SPEC_BG_COLOR: [0, ""],
 299        }
 300
 301        # <editor-fold desc="Setup defaults for pages">
 302        self._init_fill_combo_boxes()
 303        self._init_new_page()
 304        self._init_use_page()
 305        self._init_local_pred_mono_page()
 306        self._init_local_pred_multi_page()
 307        self._init_batch_analysis_page()
 308        self._view.ui.action_toggle_notebook_visibility.setVisible(False)
 309        self._view.ui.action_settings_model_w_off_colab_notebook.setVisible(False)
 310        self.last_sidebar_button = QtWidgets.QPushButton()
 311        self._view.ui.table_pred_mono_prot_to_predict.setEditTriggers(
 312            self._view.ui.table_pred_mono_prot_to_predict.NoEditTriggers,
 313        )
 314        self._view.ui.table_pred_multi_prot_to_predict.setEditTriggers(
 315            self._view.ui.table_pred_multi_prot_to_predict.NoEditTriggers,
 316        )
 317        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEditTriggers(
 318            self._view.ui.table_pred_analysis_mono_prot_to_predict.NoEditTriggers,
 319        )
 320        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEditTriggers(
 321            self._view.ui.table_pred_analysis_multi_prot_to_predict.NoEditTriggers,
 322        )
 323
 324        # TODO: temp gui changes (need to be changed in the designer)
 325        self._view.ui.lbl_hotspots_resi_show.setText("Residue(s) as sticks")
 326        self._view.ui.lbl_hotspots_resi_hide.setText("Residue(s) as sticks")
 327
 328        # fixme: should the pdf documentation be accessible through the pyssa gui?
 329        self._view.ui.action_help_docs_pdf.setText("Documentation")
 330        self._view.ui.action_help_docs_pdf.setVisible(True)
 331        self._view.ui.action_help_docs.setText("Tutorials")
 332        self._view.ui.action_help_docs.setVisible(True)
 333
 334        if self._application_settings.wsl_install == 1 and self._application_settings.local_colabfold == 0:
 335            self._view.ui.action_install_from_file.setVisible(True)
 336        else:
 337            self._view.ui.action_install_from_file.setVisible(False)
 338        # </editor-fold>
 339
 340        self._connect_all_gui_elements()
 341
 342        self._project_watcher.show_valid_options(self._view.ui)
 343        self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
 344
 345        self.threadpool = QtCore.QThreadPool()
 346        # create scratch and cache dir
 347        try:
 348            filesystem_helpers.delete_directory(constants.SCRATCH_DIR)
 349        except Exception as e:
 350            constants.PYSSA_LOGGER.warning(f"Scratch path could not be deleted. {e}")
 351        filesystem_helpers.create_directory(constants.SCRATCH_DIR)
 352        filesystem_helpers.create_directory(constants.CACHE_DIR)
 353
 354    def start_worker_thread(self, worker_obj: object, post_process_func) -> None:  # noqa: ANN001
 355        """Sets up the worker, moves the worker to a thread and starts the thread.
 356
 357        Args:
 358            worker_obj: an object of type <work>Worker (QObject).
 359            post_process_func: a function which sould be executed if the worker is finished.
 360        """
 361        self.tmp_thread = QtCore.QThread()
 362        self.tmp_worker = worker_obj
 363        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, post_process_func)
 364        self.tmp_thread.start()
 365
 366    def _setup_statusbar(self) -> None:
 367        """Sets up the status bar and fills it with the current workspace."""
 368        self._view.setStatusBar(self._view.status_bar)
 369        self._view.status_bar.showMessage(str(self._workspace_label.text()))
 370
 371    def _setup_default_configuration(self) -> None:
 372        """Sets up the default values for specific gui elements."""
 373        self._view.ui.lbl_current_project_name.setText("")
 374        # menu
 375        # side menu
 376
 377        # new project page
 378        self._view.ui.btn_new_create_project.setEnabled(False)
 379        self._view.ui.cb_new_add_reference.setCheckable(False)
 380        self._view.ui.cb_new_add_reference.setStyleSheet("color: #E1E1E1;")
 381        # open project page
 382        self._view.ui.lbl_open_status_search.setText("")
 383        self._view.ui.btn_open_open_project.setEnabled(False)
 384        # delete project page
 385        self._view.ui.lbl_delete_status_search.setText("")
 386        self._view.ui.btn_delete_delete_project.setEnabled(False)
 387        # edit project page
 388
 389        # view project page
 390
 391        # use project page
 392
 393        # new sequence page
 394        # sequence vs .pdb page
 395        self._view.ui.btn_s_v_p_start.setEnabled(False)
 396        self._view.ui.list_s_v_p_ref_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
 397        # single analysis page
 398        self._view.ui.lbl_analysis_model_chains.hide()
 399        self._view.ui.list_analysis_model_chains.hide()
 400        self._view.ui.btn_analysis_back.hide()
 401        self._view.ui.btn_analysis_start.hide()
 402        # batch analysis page
 403
 404        # results page
 405
 406        # image page
 407
 408    def _connect_all_gui_elements(self) -> None:
 409        """Connects all gui elements with their corresponding slots."""
 410        self._view.ui.btn_info.clicked.connect(self.open_page_information)
 411
 412        # <editor-fold desc="Menu">
 413        self._view.ui.action_file_quit.triggered.connect(self.quit_app)
 414        self._view.ui.action_file_restore_settings.triggered.connect(self.restore_settings)
 415        self._view.ui.action_settings_edit_all.triggered.connect(self.open_settings_global)
 416        self._view.ui.action_help_docs.triggered.connect(self.open_tutorial)
 417        self._view.ui.action_help_docs_pdf.triggered.connect(self.open_documentation)
 418        self._view.ui.action_help_about.triggered.connect(self.open_about)
 419        self._view.ui.action_settings_open_logs.triggered.connect(self.open_logs)
 420        self._view.ui.action_settings_clear_logs.triggered.connect(self.clear_all_log_files)
 421        self._view.ui.action_help_changelog.triggered.connect(self.open_release_notes_in_standard_application)
 422        # </editor-fold>
 423
 424        # <editor-fold desc="Side Menu">
 425        self._view.ui.btn_new_page.clicked.connect(self.display_new_page)
 426        self._view.ui.btn_open_page.clicked.connect(self.display_open_page)
 427        self._view.ui.btn_delete_page.clicked.connect(self.display_delete_page)
 428        self._view.ui.btn_save_project.clicked.connect(self.save_project)
 429        self._view.ui.btn_edit_page.clicked.connect(self.display_edit_page)
 430        self._view.ui.btn_view_page.clicked.connect(self.display_view_page)
 431        self._view.ui.btn_use_page.clicked.connect(self.display_use_page)
 432        self._view.ui.btn_import_project.clicked.connect(self.import_project)
 433        self._view.ui.btn_export_project.clicked.connect(self.export_current_project)
 434        self._view.ui.btn_close_project.clicked.connect(self.close_project)
 435        self._view.ui.btn_pred_cloud_monomer_page.clicked.connect(self.display_esm_pred_mono)
 436        self._view.ui.btn_pred_local_monomer_page.clicked.connect(self.display_local_pred_mono)
 437        self._view.ui.btn_pred_local_multimer_page.clicked.connect(self.display_local_pred_multi)
 438        self._view.ui.btn_prediction_abort.clicked.connect(self.abort_prediction)
 439        self._view.ui.btn_pred_analysis_monomer_page.clicked.connect(self.display_monomer_pred_analysis)
 440        self._view.ui.btn_pred_analysis_multimer_page.clicked.connect(self.display_multimer_pred_analysis)
 441        self._view.ui.btn_batch_analysis_page.clicked.connect(self.display_job_analysis_page)
 442        self._view.ui.btn_image_analysis_page.clicked.connect(self.display_image_analysis_page)
 443        self._view.ui.btn_results_page.clicked.connect(self.display_results_page)
 444        # self._view.ui.btn_analysis_abort.clicked.connect(self.abort_analysis)
 445        self._view.ui.btn_manage_session.clicked.connect(self.display_manage_pymol_session)
 446        self._view.ui.btn_image_page.clicked.connect(self.display_image_page)
 447        self._view.ui.btn_hotspots_page.clicked.connect(self.display_hotspots_page)
 448
 449        # </editor-fold>
 450
 451        # <editor-fold desc="New project page">
 452        self._view.ui.btn_new_choose_reference.clicked.connect(self.load_reference_in_project)
 453        self._view.ui.txt_new_project_name.textChanged.connect(self.validate_project_name)
 454        self._view.ui.txt_new_choose_reference.textChanged.connect(self.validate_reference_in_project)
 455        self._view.ui.cb_new_add_reference.stateChanged.connect(self.show_add_reference)
 456        self._view.ui.btn_new_create_project.clicked.connect(self.create_new_project)
 457
 458        # </editor-fold>
 459
 460        # <editor-fold desc="Open project page">
 461        self._view.ui.btn_open_open_project.clicked.connect(self.open_project)
 462        self._view.ui.list_open_projects.doubleClicked.connect(self.open_project)
 463        self._view.ui.txt_open_search.textChanged.connect(self.validate_open_search)
 464        self._view.ui.txt_open_selected_project.textChanged.connect(self.activate_open_button)
 465        self._view.ui.list_open_projects.currentItemChanged.connect(self.select_project_from_open_list)
 466
 467        # </editor-fold>
 468
 469        # <editor-fold desc="Delete project page">
 470        self._view.ui.btn_delete_delete_project.clicked.connect(self.delete_project)
 471        self._view.ui.txt_delete_search.textChanged.connect(self.validate_delete_search)
 472        self._view.ui.txt_delete_selected_projects.textChanged.connect(self.activate_delete_button)
 473        self._view.ui.list_delete_projects.currentItemChanged.connect(self.select_project_from_delete_list)
 474
 475        # </editor-fold>
 476
 477        # <editor-fold desc="Edit project page">
 478        self._view.ui.btn_edit_page.clicked.connect(self.display_edit_page)
 479        self._view.ui.list_edit_project_proteins.currentItemChanged.connect(self.check_for_cleaning)
 480        self._view.ui.btn_edit_clean_new_prot.clicked.connect(self.clean_protein_new)
 481        self._view.ui.btn_edit_clean_update_prot.clicked.connect(self.clean_protein_update)
 482        self._view.ui.btn_edit_project_delete.clicked.connect(self.delete_protein)
 483        self._view.ui.btn_edit_existing_protein_struct.clicked.connect(self.add_existing_protein)
 484        self._view.ui.btn_edit_project_save.clicked.connect(self.save_selected_protein_structure_as_pdb_file)
 485        self._view.ui.btn_edit_protein_rename.clicked.connect(self.rename_selected_protein_structure)
 486        # </editor-fold>
 487
 488        # <editor-fold desc="View project page">
 489        self._view.ui.btn_view_project_show.clicked.connect(self.view_sequence)
 490        self._view.ui.btn_view_project_show_structure.clicked.connect(self.view_structure)
 491        self._view.ui.list_view_project_proteins.doubleClicked.connect(self.view_sequence)
 492        self._view.ui.list_view_project_proteins.itemClicked.connect(self.view_show_options)
 493        # </editor-fold>
 494
 495        # <editor-fold desc="Use project page">
 496        self._view.ui.txt_use_project_name.textChanged.connect(self.validate_use_project_name)
 497        self._view.ui.btn_use_next.clicked.connect(self.show_protein_selection_for_use)
 498        self._view.ui.txt_use_search.textChanged.connect(self.validate_use_search)
 499        self._view.ui.btn_use_add_available_protein_structures.clicked.connect(
 500            self.add_protein_structure_to_new_project,
 501        )
 502        self._view.ui.list_use_available_protein_structures.doubleClicked.connect(
 503            self.add_protein_structure_to_new_project,
 504        )
 505        self._view.ui.list_use_available_protein_structures.itemClicked.connect(self.use_enable_add)
 506        self._view.ui.btn_use_remove_selected_protein_structures.clicked.connect(
 507            self.remove_protein_structure_to_new_project,
 508        )
 509        self._view.ui.list_use_selected_protein_structures.doubleClicked.connect(
 510            self.remove_protein_structure_to_new_project,
 511        )
 512        self._view.ui.list_use_selected_protein_structures.itemClicked.connect(self.use_enable_remove)
 513        self._view.ui.btn_use_back.clicked.connect(self.hide_protein_selection_for_use)
 514        self._view.ui.btn_use_create_new_project.clicked.connect(self.pre_create_use_project)
 515
 516        # </editor-fold>
 517
 518        # <editor-fold desc="ESMFold Monomer Prediction page">
 519        self._view.ui.btn_esm_seq_to_predict.clicked.connect(self.cloud_esm_add_seq_to_predict)
 520        self._view.ui.btn_esm_seq_to_predict_remove.clicked.connect(self.cloud_esm_remove)
 521        self._view.ui.btn_esm_next.clicked.connect(self.cloud_esm_next)
 522        self._view.ui.btn_esm_back.clicked.connect(self.cloud_esm_back)
 523        self._view.ui.btn_esm_next_2.clicked.connect(self.cloud_esm_add_protein)
 524        self._view.ui.btn_esm_back_2.clicked.connect(self.cloud_esm_back_2)
 525        self._view.ui.txt_esm_prot_name.textChanged.connect(self.cloud_esm_validate_protein_name)
 526        self._view.ui.txt_esm_prot_seq.textChanged.connect(self.cloud_esm_validate_protein_sequence)
 527        self._view.ui.btn_esm_predict.clicked.connect(self.predict_esm_monomer)
 528
 529        self._view.ui.table_esm_prot_to_predict.itemSelectionChanged.connect(self.cloud_esm_item_changed)
 530        # </editor-fold>
 531
 532        # <editor-fold desc="Monomer local prediction page">
 533        self._view.ui.btn_pred_mono_seq_to_predict.clicked.connect(self.local_pred_mono_add_seq_to_predict)
 534        self._view.ui.btn_pred_mono_seq_to_predict_remove.clicked.connect(self.local_pred_mono_remove)
 535        self._view.ui.btn_pred_mono_next.clicked.connect(self.local_pred_mono_next)
 536        self._view.ui.btn_pred_mono_back.clicked.connect(self.local_pred_mono_back)
 537        self._view.ui.btn_pred_mono_add_protein.clicked.connect(self.local_pred_mono_add_protein)
 538        self._view.ui.btn_pred_mono_back_2.clicked.connect(self.local_pred_mono_back_2)
 539        self._view.ui.txt_pred_mono_prot_name.textChanged.connect(self.local_pred_mono_validate_protein_name)
 540        self._view.ui.txt_pred_mono_seq_name.textChanged.connect(self.local_pred_mono_validate_protein_sequence)
 541        self._view.ui.btn_pred_mono_advanced_config.clicked.connect(self.show_prediction_configuration)
 542        self._view.ui.btn_pred_mono_predict.clicked.connect(self.predict_local_monomer)
 543
 544        self._view.ui.table_pred_mono_prot_to_predict.itemSelectionChanged.connect(self.local_pred_mono_item_changed)
 545        # </editor-fold>
 546
 547        # <editor-fold desc="Multimer prediction page">
 548        self._view.ui.btn_pred_multi_prot_to_predict_add.clicked.connect(self.local_pred_multi_add)
 549        self._view.ui.btn_pred_multi_prot_to_predict_remove.clicked.connect(self.local_pred_multi_remove)
 550        self._view.ui.btn_pred_multi_next.clicked.connect(self.local_pred_multi_next)
 551        self._view.ui.btn_pred_multi_back.clicked.connect(self.local_pred_multi_back)
 552        self._view.ui.btn_pred_multi_prot_to_predict_add_2.clicked.connect(self.local_pred_multi_prot_to_predict_add_2)
 553        self._view.ui.btn_pred_multi_back_2.clicked.connect(self.local_pred_multi_back_2)
 554        self._view.ui.txt_pred_multi_prot_name.textChanged.connect(self.local_pred_multi_validate_protein_name)
 555        self._view.ui.txt_pred_multi_prot_seq.textChanged.connect(self.local_pred_multi_validate_protein_sequence)
 556        self._view.ui.btn_pred_multi_prot_seq_add.clicked.connect(self.local_pred_multi_add_sequence_to_list)
 557        self._view.ui.btn_pred_multi_prot_seq_overview_remove.clicked.connect(
 558            self.local_pred_multi_remove_sequence_to_list,
 559        )
 560        self._view.ui.btn_pred_multi_advanced_config.clicked.connect(self.show_prediction_configuration)
 561        self._view.ui.btn_pred_multi_predict.clicked.connect(self.predict_local_multimer)
 562
 563        self._view.ui.list_pred_multi_prot_seq_overview.itemClicked.connect(
 564            self.local_pred_multi_prot_seq_overview_item_changed,
 565        )
 566        self._view.ui.table_pred_multi_prot_to_predict.itemSelectionChanged.connect(
 567            self.local_pred_multi_prot_to_predict_item_changed,
 568        )
 569        # </editor-fold>
 570
 571        # <editor-fold desc="Monomer Prediction + Analysis page">
 572        # <editor-fold desc="Prediction section">
 573        self._view.ui.btn_pred_analysis_mono_seq_to_predict.clicked.connect(self.mono_pred_analysis_add_seq_to_predict)
 574        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.clicked.connect(
 575            self.mono_pred_analysis_remove_protein_to_predict,
 576        )
 577        self._view.ui.btn_pred_analysis_mono_next.clicked.connect(self.mono_pred_analysis_next)
 578        self._view.ui.btn_pred_analysis_mono_back.clicked.connect(self.mono_pred_analysis_back)
 579        self._view.ui.btn_pred_analysis_mono_add_protein.clicked.connect(self.mono_pred_analysis_add_protein)
 580        self._view.ui.btn_pred_analysis_mono_back_2.clicked.connect(self.mono_pred_analysis_back_2)
 581        self._view.ui.txt_pred_analysis_mono_prot_name.textChanged.connect(
 582            self.mono_pred_analysis_validate_protein_name,
 583        )
 584        self._view.ui.txt_pred_analysis_mono_seq_name.textChanged.connect(
 585            self.mono_pred_analysis_validate_protein_sequence,
 586        )
 587        self._view.ui.btn_pred_mono_advanced_config_2.clicked.connect(self.show_prediction_configuration)
 588        self._view.ui.btn_pred_analysis_mono_go_analysis_setup.clicked.connect(self.switch_monomer_pred_analysis_tab)
 589        self._view.ui.table_pred_analysis_mono_prot_to_predict.itemSelectionChanged.connect(
 590            self.mono_pred_analysis_prediction_overview_item_clicked,
 591        )
 592
 593        # </editor-fold>
 594
 595        # <editor-fold desc="Analysis section">
 596        self._view.ui.btn_pred_analysis_mono_add.clicked.connect(self.mono_pred_analysis_structure_analysis_add)
 597        self._view.ui.btn_pred_analysis_mono_remove.clicked.connect(self.remove_mono_pred_analysis_analysis_run)
 598        self._view.ui.btn_pred_analysis_mono_back_3.clicked.connect(self.mono_pred_analysis_structure_analysis_back_3)
 599        self._view.ui.btn_pred_analysis_mono_next_2.clicked.connect(self.mono_pred_analysis_structure_analysis_next_2)
 600        self._view.ui.btn_pred_analysis_mono_back_4.clicked.connect(self.mono_pred_analysis_structure_analysis_back_4)
 601        self._view.ui.btn_pred_analysis_mono_next_3.clicked.connect(self.mono_pred_analysis_structure_analysis_next_3)
 602        self._view.ui.btn_pred_analysis_mono_back_5.clicked.connect(self.mono_pred_analysis_structure_analysis_back_5)
 603        self._view.ui.btn_pred_analysis_mono_next_4.clicked.connect(self.mono_pred_analysis_structure_analysis_next_4)
 604        self._view.ui.box_pred_analysis_mono_prot_struct_1.currentIndexChanged.connect(
 605            self.check_mono_pred_analysis_if_prot_structs_are_filled,
 606        )
 607        self._view.ui.box_pred_analysis_mono_prot_struct_2.currentIndexChanged.connect(
 608            self.check_mono_pred_analysis_if_prot_structs_are_filled,
 609        )
 610        self._view.ui.list_pred_analysis_mono_ref_chains.itemSelectionChanged.connect(
 611            self.count_mono_pred_analysis_selected_chains_for_prot_struct_1,
 612        )
 613        self._view.ui.list_pred_analysis_mono_model_chains.itemSelectionChanged.connect(
 614            self.check_mono_pred_analysis_if_same_no_of_chains_selected,
 615        )
 616        self._view.ui.btn_pred_analysis_mono_back_pred_setup.clicked.connect(self.switch_monomer_pred_analysis_tab)
 617        self._view.ui.btn_pred_analysis_mono_start.clicked.connect(self.start_monomer_prediction_analysis)
 618        self._view.ui.list_pred_analysis_mono_overview.clicked.connect(
 619            self.mono_pred_analysis_structure_analysis_overview_clicked,
 620        )
 621
 622        # </editor-fold>
 623
 624        # </editor-fold>
 625
 626        # <editor-fold desc="Multimer Prediction + Analysis page">
 627        # <editor-fold desc="Prediction section">
 628        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add.clicked.connect(self.multi_pred_analysis_add)
 629        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.clicked.connect(
 630            self.multi_pred_analysis_remove_protein_to_predict,
 631        )
 632        self._view.ui.btn_pred_analysis_multi_next.clicked.connect(self.multi_pred_analysis_next)
 633        self._view.ui.btn_pred_analysis_multi_back.clicked.connect(self.multi_pred_analysis_back)
 634        self._view.ui.btn_pred_analysis_multi_prot_seq_add.clicked.connect(
 635            self.multi_pred_analysis_add_sequence_to_list,
 636        )
 637        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.clicked.connect(
 638            self.multi_pred_analysis_remove_sequence_to_list,
 639        )
 640        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.clicked.connect(
 641            self.multi_pred_analysis_add_protein_to_predict,
 642        )
 643        self._view.ui.btn_pred_analysis_multi_back_2.clicked.connect(self.multi_pred_analysis_back_2)
 644
 645        self._view.ui.txt_pred_analysis_multi_prot_name.textChanged.connect(
 646            self.multi_pred_analysis_validate_protein_name,
 647        )
 648        self._view.ui.txt_pred_analysis_multi_prot_seq.textChanged.connect(
 649            self.multi_pred_analysis_validate_protein_sequence,
 650        )
 651        self._view.ui.btn_pred_analysis_multi_advanced_config.clicked.connect(self.show_prediction_configuration)
 652        self._view.ui.btn_pred_analysis_multi_go_analysis_setup.clicked.connect(self.switch_multimer_pred_analysis_tab)
 653
 654        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clicked.connect(
 655            self.multi_pred_analysis_prot_seq_overview_item_changed,
 656        )
 657        self._view.ui.table_pred_analysis_multi_prot_to_predict.itemSelectionChanged.connect(
 658            self.multi_pred_analysis_prot_to_predict_item_changed,
 659        )
 660
 661        # </editor-fold>
 662
 663        # <editor-fold desc="Analysis section">
 664        self._view.ui.btn_pred_analysis_multi_add.clicked.connect(self.multi_pred_analysis_structure_analysis_add)
 665        self._view.ui.btn_pred_analysis_multi_remove.clicked.connect(self.remove_multi_pred_analysis_analysis_run)
 666        self._view.ui.btn_pred_analysis_multi_back_3.clicked.connect(self.multi_pred_analysis_structure_analysis_back_3)
 667        self._view.ui.btn_pred_analysis_multi_next_2.clicked.connect(self.multi_pred_analysis_structure_analysis_next_2)
 668        self._view.ui.btn_pred_analysis_multi_back_4.clicked.connect(self.multi_pred_analysis_structure_analysis_back_4)
 669        self._view.ui.btn_pred_analysis_multi_next_3.clicked.connect(self.multi_pred_analysis_structure_analysis_next_3)
 670        self._view.ui.btn_pred_analysis_multi_back_5.clicked.connect(self.multi_pred_analysis_structure_analysis_back_5)
 671        self._view.ui.btn_pred_analysis_multi_next_4.clicked.connect(self.multi_pred_analysis_structure_analysis_next_4)
 672        self._view.ui.box_pred_analysis_multi_prot_struct_1.currentIndexChanged.connect(
 673            self.check_multi_pred_analysis_if_prot_structs_are_filled,
 674        )
 675        self._view.ui.box_pred_analysis_multi_prot_struct_2.currentIndexChanged.connect(
 676            self.check_multi_pred_analysis_if_prot_structs_are_filled,
 677        )
 678        self._view.ui.list_pred_analysis_multi_ref_chains.itemSelectionChanged.connect(
 679            self.count_multi_pred_analysis_selected_chains_for_prot_struct_1,
 680        )
 681        self._view.ui.list_pred_analysis_multi_model_chains.itemSelectionChanged.connect(
 682            self.check_multi_pred_analysis_if_same_no_of_chains_selected,
 683        )
 684        self._view.ui.btn_pred_analysis_multi_back_pred_setup.clicked.connect(self.switch_multimer_pred_analysis_tab)
 685        self._view.ui.btn_pred_analysis_multi_start.clicked.connect(self.start_multimer_prediction_analysis)
 686        self._view.ui.list_pred_analysis_multi_overview.clicked.connect(
 687            self.multi_pred_analysis_structure_analysis_overview_clicked,
 688        )
 689        # </editor-fold>
 690
 691        # </editor-fold>
 692
 693        # <editor-fold desc="Structure analysis page">
 694        self._view.ui.btn_analysis_batch_add.clicked.connect(self.structure_analysis_add)
 695        self._view.ui.btn_analysis_batch_remove.clicked.connect(self.remove_analysis_run)
 696        self._view.ui.btn_analysis_batch_back.clicked.connect(self.structure_analysis_back)
 697        self._view.ui.btn_analysis_batch_next.clicked.connect(self.structure_analysis_next)
 698        self._view.ui.btn_analysis_batch_back_2.clicked.connect(self.structure_analysis_back_2)
 699        self._view.ui.btn_analysis_batch_next_2.clicked.connect(self.structure_analysis_next_2)
 700        self._view.ui.btn_analysis_batch_back_3.clicked.connect(self.structure_analysis_back_3)
 701        self._view.ui.btn_analysis_batch_next_3.clicked.connect(self.structure_analysis_next_3)
 702        self._view.ui.box_analysis_batch_prot_struct_1.currentIndexChanged.connect(
 703            self.check_if_prot_structs_are_filled_batch,
 704        )
 705        self._view.ui.box_analysis_batch_prot_struct_2.currentIndexChanged.connect(
 706            self.check_if_prot_structs_are_filled_batch,
 707        )
 708        self._view.ui.list_analysis_batch_ref_chains.itemSelectionChanged.connect(
 709            self.count_batch_selected_chains_for_prot_struct_1,
 710        )
 711        self._view.ui.list_analysis_batch_model_chains.itemSelectionChanged.connect(
 712            self.check_if_same_no_of_chains_selected_batch,
 713        )
 714        self._view.ui.btn_analysis_batch_start.clicked.connect(self.start_process_batch)
 715        self._view.ui.list_analysis_batch_overview.clicked.connect(self.structure_analysis_overview_clicked)
 716
 717        # </editor-fold>
 718
 719        # <editor-fold desc="Analysis images page">
 720        self._view.ui.btn_add_analysis_images_struct_analysis.clicked.connect(
 721            self.add_protein_pair_to_image_creation_queue,
 722        )
 723        self._view.ui.list_analysis_images_struct_analysis.doubleClicked.connect(
 724            self.add_protein_pair_to_image_creation_queue,
 725        )
 726        self._view.ui.list_analysis_images_struct_analysis.clicked.connect(self.analysis_images_enable_add)
 727        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.clicked.connect(
 728            self.remove_protein_pair_from_image_creation_queue,
 729        )
 730        self._view.ui.list_analysis_images_creation_struct_analysis.doubleClicked.connect(
 731            self.remove_protein_pair_from_image_creation_queue,
 732        )
 733        self._view.ui.list_analysis_images_creation_struct_analysis.clicked.connect(self.analysis_images_enable_remove)
 734        self._view.ui.btn_start_automatic_image_creation.clicked.connect(self.start_automatic_image_creation)
 735
 736        # </editor-fold>
 737
 738        # <editor-fold desc="Results page">
 739        self._view.ui.cb_results_analysis_options.currentIndexChanged.connect(self.load_results)
 740        self._view.ui.btn_color_rmsd.clicked.connect(self.color_protein_pair_by_rmsd)
 741        self._view.ui.btn_view_struct_alignment.clicked.connect(self.display_structure_alignment)
 742        self._view.ui.btn_view_distance_plot.clicked.connect(self.display_distance_plot)
 743        self._view.ui.btn_view_distance_histogram.clicked.connect(self.display_distance_histogram)
 744        self._view.ui.btn_view_interesting_region.clicked.connect(self.display_interesting_region)
 745        self._view.ui.btn_view_distance_table.clicked.connect(self.display_distance_table)
 746
 747        # </editor-fold>
 748
 749        # <editor-fold desc="Manage">
 750        self._view.ui.box_manage_choose_protein.activated.connect(self.choose_manage_open_protein)
 751        self._view.ui.box_manage_choose_color.activated.connect(self.choose_manage_color_selected_protein)
 752        self._view.ui.box_manage_choose_representation.activated.connect(self.choose_manage_representation)
 753        self._view.ui.box_manage_choose_bg_color.activated.connect(self.choose_manage_bg_color)
 754        self._view.ui.btn_disulfid_bond_show.clicked.connect(self.show_disulfid_bonds_as_sticks)
 755        self._view.ui.btn_disulfid_bond_hide.clicked.connect(self.hide_disulfid_bonds_as_sticks)
 756
 757        # </editor-fold>
 758
 759        # <editor-fold desc="Image page">
 760        self._view.ui.btn_update_scene.clicked.connect(self.update_scene)
 761        self._view.ui.btn_save_scene.clicked.connect(self.save_scene)
 762        self._view.ui.btn_save_image.clicked.connect(self.save_image)
 763        self._view.ui.btn_preview_image.clicked.connect(self.preview_image)
 764        self._view.ui.box_representation.activated.connect(self.show_representation)
 765        self._view.ui.box_bg_color.activated.connect(self.choose_bg_color)
 766        self._view.ui.box_renderer.activated.connect(self.choose_renderer)
 767        self._view.ui.box_ray_trace_mode.activated.connect(self.choose_ray_trace_mode)
 768        self._view.ui.box_ray_texture.activated.connect(self.choose_ray_texture)
 769        self._view.ui.cb_transparent_bg.stateChanged.connect(self.decide_transparent_bg)
 770        self._view.ui.cb_ray_tracing.stateChanged.connect(self.decide_ray_tracing)
 771
 772        # </editor-fold>
 773
 774        # <editor-fold desc="Hotspots page">
 775        self._view.ui.list_hotspots_choose_protein.currentItemChanged.connect(self.open_protein_for_hotspots)
 776        self._view.ui.btn_hotspots_resi_show.clicked.connect(self.show_resi_sticks)
 777        self._view.ui.btn_hotspots_resi_hide.clicked.connect(self.hide_resi_sticks)
 778        self._view.ui.btn_hotspots_resi_zoom.clicked.connect(self.zoom_resi_position)
 779
 780        # </editor-fold>
 781
 782    def restore_settings(self) -> None:
 783        """Restores the settings.xml file to the default values."""
 784        out = gui_utils.warning_dialog_restore_settings("Are you sure you want to restore all settings?")
 785        if out:
 786            tools.restore_default_settings(self._application_settings)
 787            self._view.status_bar.showMessage("Settings were successfully restored.")
 788            logging.info("Settings were successfully restored.")
 789        else:
 790            self._view.status_bar.showMessage("Settings were not modified.")
 791            logging.info("Settings were not modified.")
 792
 793    def quit_app(self) -> None:
 794        """Closes the entire plugin."""
 795        self._view.quit_app()
 796
 797    @staticmethod
 798    def clear_all_log_files() -> None:
 799        """Clears all log files generated under .pyssa/logs."""
 800        response = basic_boxes.yes_or_no(
 801            "Clear log files",
 802            "Are you sure you want to delete all log files?",
 803            QtWidgets.QMessageBox.Information,
 804        )
 805        if response:
 806            try:
 807                shutil.rmtree(str(constants.LOG_PATH))
 808            except PermissionError:
 809                print("The active log file was not deleted.")
 810            if len(os.listdir(str(constants.LOG_PATH))) == 1:
 811                basic_boxes.ok("Clear log files", "All log files could be deleted.", QtWidgets.QMessageBox.Information)
 812                constants.PYSSA_LOGGER.info("All log files were deleted.")
 813            else:
 814                basic_boxes.ok("Clear log files", "Not all log files could be deleted.", QtWidgets.QMessageBox.Warning)
 815                constants.PYSSA_LOGGER.warning("Not all log files were deleted!")
 816
 817    # <editor-fold desc="Open extra views">
 818    def open_settings_global(self) -> None:
 819        """Opens the dialog for the global settings."""
 820        dialog = dialog_settings_global.DialogSettingsGlobal()
 821        dialog.exec_()
 822        self._application_settings = self._application_settings.deserialize_settings()
 823        globals.g_settings = self._application_settings
 824        self._workspace_path = globals.g_settings.workspace_path
 825        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
 826        self._setup_statusbar()
 827
 828    def open_logs(self) -> None:
 829        """Opens a file explorer with all log files and can open a log file in the default application."""
 830        file_dialog = QtWidgets.QFileDialog()
 831        log_path = str(constants.LOG_PATH)
 832        file_dialog.setDirectory(log_path)
 833        file_path, _ = file_dialog.getOpenFileName(self._view, "Select a log file to open", "", "LOG File (*.log)")
 834        if file_path:
 835            os.startfile(file_path)
 836
 837    @staticmethod
 838    def open_tutorial() -> None:
 839        """Opens the official tutorial pdf file."""
 840        tmp_dialog = dialog_tutorial_videos.TutorialVideosDialog()
 841        tmp_dialog.exec_()
 842
 843    @staticmethod
 844    def open_documentation() -> None:
 845        """Opens the official plugin documentation as PDF."""
 846        os.startfile(constants.DOCS_PATH)
 847
 848    @staticmethod
 849    def open_about() -> None:
 850        """Opens the About dialog."""
 851        dialog = dialog_about.DialogAbout()
 852        dialog.exec_()
 853
 854    def open_page_information(self) -> None:
 855        """Opens the message box, to display extra information based on the page."""
 856        with open(
 857            f"{constants.PAGE_HELP_PATHS_DICT[self._view.ui.lbl_page_title.text()]}",
 858            "r",
 859            encoding="utf-8",
 860        ) as file:
 861            html_content = file.read()
 862            file.close()
 863        tmp_dialog = dialog_help.DialogHelp(html_content)
 864        tmp_dialog.exec_()
 865
 866    @staticmethod
 867    def open_release_notes_in_standard_application() -> None:
 868        """Opens the release notes in the default app."""
 869        os.startfile(constants.CHANGELOG_HTML_PATH)
 870
 871    # </editor-fold>
 872
 873    # def open_change_log(self) -> None:
 874    #     """Opens change log based on the last run pyssa version.
 875    #
 876    #     Notes:
 877    #         Change log opens only if the last pyssa version is older than the current one.
 878    #     """
 879    #     last_version = f"v{self.get_version_from_latest_log_file(self.get_filepath_of_latest_log_file())}"
 880    #     if last_version != constants.VERSION_NUMBER:
 881    #         self.open_release_notes_in_standard_application()
 882    #
 883    # def get_version_from_latest_log_file(self, a_filepath: pathlib.Path) -> str:
 884    #     """Gets the pyssa version of the latest log file.
 885    #
 886    #     Args:
 887    #         a_filepath: the filepath to the latest log file.
 888    #     """
 889    #     with open(str(a_filepath), "r", encoding="utf-8") as file:
 890    #         file_content = file.read()
 891    #         file.close()
 892    #     # Define the regex pattern to extract the version number
 893    #     pattern = r"PySSA started with version v(\d+\.\d+\.\d+)"
 894    #     # Search for the pattern in the text
 895    #     match = re.search(pattern, file_content)
 896    #     # Check if a match is found
 897    #     if match:
 898    #         version_number = match.group(1)
 899    #         print("Extracted version number:", version_number)
 900    #     else:
 901    #         print("Version number not found in the text.")
 902    #         version_number = None
 903    #     return version_number
 904    #
 905    # def get_filepath_of_latest_log_file(self) -> pathlib.Path:
 906    #     """Gets the filepath of the latest log file.
 907    #
 908    #     Raises:
 909    #         FileNotFoundError: If no log files can be found in the log directory.
 910    #     """
 911    #     # Get a list of files in the directory
 912    #     files = [f for f in os.listdir(constants.LOG_PATH) if os.path.isfile(os.path.join(constants.LOG_PATH, f))]
 913    #     # Filter files to include only log files (adjust the extension accordingly)
 914    #     log_files = [f for f in files if f.endswith(".log")]
 915    #     # Check if there are any log files
 916    #     if not log_files:
 917    #         raise FileNotFoundError("No log files found in the directory.")
 918    #     # Get the full path of each log file
 919    #     log_files_paths = [os.path.join(constants.LOG_PATH, f) for f in log_files]
 920    #     # Get the latest log file based on modification time
 921    #     latest_log_file_index = log_files_paths.index(max(log_files_paths, key=os.path.getmtime)) - 1
 922    #     return pathlib.Path(log_files_paths[latest_log_file_index])
 923
 924    # <editor-fold desc="Logic related methods">
 925
 926    # <editor-fold desc="New project page functions">
 927    def create_new_project(self) -> None:
 928        """Creates a new project with the content of the new page."""
 929        # <editor-fold desc="Checks">
 930        if self._application_settings.wsl_install == 0:
 931            basic_boxes.ok(
 932                "Create new project",
 933                "Please install local colabfold to create a project!",
 934                QtWidgets.QMessageBox.Warning,
 935            )
 936            return
 937        if self._application_settings.local_colabfold == 0:
 938            basic_boxes.ok(
 939                "Create new project",
 940                "Please install local colabfold to create a project!",
 941                QtWidgets.QMessageBox.Warning,
 942            )
 943            return
 944
 945        # </editor-fold>
 946
 947        self._view.wait_spinner.start()
 948        an_add_protein_flag: bool = False
 949        if self._view.ui.cb_new_add_reference.checkState() == 2:
 950            an_add_protein_flag = True
 951
 952        self._active_task = tasks.Task(
 953            target=main_presenter_async.create_new_project,
 954            args=(
 955                self._view.ui.txt_new_project_name.text(),
 956                self._workspace_path,
 957                an_add_protein_flag,
 958                self._view.ui.txt_new_choose_reference.text(),
 959            ),
 960            post_func=self.__await_create_new_project,
 961        )
 962        self._active_task.start()
 963        self.update_status("Creating new project ...")
 964
 965    def __await_create_new_project(self, a_result: tuple) -> None:
 966        self._current_project: "project.Project" = a_result[1]
 967        constants.PYSSA_LOGGER.info(f"Created the project {self._current_project.get_project_name()}.")
 968        self._view.ui.cb_new_add_reference.setCheckState(0)
 969        self._project_watcher.current_project = self._current_project
 970        constants.PYSSA_LOGGER.info(
 971            f"{self._project_watcher.current_project.get_project_name()} is the current project.",
 972        )
 973        self._project_watcher.on_home_page = False
 974        # update gui
 975        self._project_watcher.show_valid_options(self._view.ui)
 976        self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
 977        self.main_window_state = main_window_state.MainWindowState(
 978            results_state.ResultsState(),
 979            image_state.ImageState(),
 980        )
 981        self.display_view_page()
 982        self._view.wait_spinner.stop()
 983        self.update_status(self._workspace_status)
 984
 985    # </editor-fold>
 986
 987    # <editor-fold desc="Open project page functions">
 988    def open_project(self) -> None:
 989        """Initiates the task to open an existing project."""
 990        self._view.wait_spinner.start()
 991        self._active_task = tasks.Task(
 992            target=main_presenter_async.open_project,
 993            args=(
 994                self._workspace_path,
 995                self._view.ui.txt_open_selected_project.text(),
 996                self._application_settings,
 997            ),
 998            post_func=self.__await_open_project,
 999        )
1000        self._active_task.start()
1001        self.update_status("Opening existing project ...")
1002
1003    def __await_open_project(self, a_result: tuple) -> None:
1004        self._current_project = a_result[1]
1005        self._project_watcher.current_project = self._current_project
1006        constants.PYSSA_LOGGER.info(
1007            f"{self._project_watcher.current_project.get_project_name()} is the current project.",
1008        )
1009        self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
1010        self._project_watcher.on_home_page = False
1011        self._project_watcher.show_valid_options(self._view.ui)
1012        cmd.reinitialize()
1013        self._view.ui.btn_manage_session.hide()
1014        self.display_view_page()
1015        self.main_window_state = main_window_state.MainWindowState(
1016            results_state.ResultsState(),
1017            image_state.ImageState(),
1018        )
1019        self._view.wait_spinner.stop()
1020        self.update_status(self._workspace_status)
1021
1022    # </editor-fold>
1023
1024    # <editor-fold desc="Delete project page functions">
1025    def delete_project(self) -> None:
1026        """Deletes an existing project."""
1027        # popup message which warns the user that the selected project gets deleted
1028        response: bool = gui_utils.warning_message_project_gets_deleted()
1029        tmp_project_name = self._view.ui.txt_delete_selected_projects.text()
1030        if response is True:
1031            os.remove(pathlib.Path(f"{self._workspace_path}/{self._view.ui.txt_delete_selected_projects.text()}"))
1032            if self._view.ui.txt_delete_selected_projects.text() == self._view.ui.lbl_current_project_name.text():
1033                self._view.ui.lbl_current_project_name.clear()
1034            self._view.ui.txt_delete_selected_projects.clear()
1035            # update list
1036            self._view.ui.list_delete_projects.clear()
1037            # pre-process
1038            self._view.status_bar.showMessage(self._workspace_label.text())
1039            self._view.ui.list_delete_projects.clear()
1040            self._view.status_bar.showMessage(self._workspace_label.text())
1041            tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
1042            constants.PYSSA_LOGGER.info(f"The project {tmp_project_name} was successfully deleted.")
1043            if self._view.ui.list_delete_projects.count() == 0:
1044                self.display_home_page()
1045                self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
1046        else:
1047            constants.PYSSA_LOGGER.info("No project has been deleted. No changes were made.")
1048
1049    # </editor-fold>
1050
1051    # <editor-fold desc="Save project functions">
1052    def save_project(self) -> None:
1053        """Saves the project.xml."""
1054        self._view.wait_spinner.start()
1055        self.last_sidebar_button = styles.color_sidebar_buttons(
1056            self.last_sidebar_button,
1057            self._view.ui.btn_save_project,
1058        )
1059        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1060        self._active_task = tasks.Task(
1061            target=main_presenter_async.save_project,
1062            args=(self._current_project, 0),
1063            post_func=self.__await_save_project,
1064        )
1065        self._active_task.start()
1066        self.update_status("Saving current project ...")
1067
1068    def __await_save_project(self, result: tuple) -> None:
1069        self._view.wait_spinner.stop()
1070        self.update_status(self._workspace_status)
1071        basic_boxes.ok("Save Project", "The project was successfully saved.", QtWidgets.QMessageBox.Information)
1072
1073    # </editor-fold>
1074
1075    # <editor-fold desc="Edit project page functions">
1076    def check_for_cleaning(self) -> None:
1077        """Checks if the selected protein can be cleaned."""
1078        self._view.wait_spinner.start()
1079        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1080        try:
1081            tmp_protein_name: str = self._view.ui.list_edit_project_proteins.currentItem().text()
1082        except AttributeError:
1083            self._view.wait_spinner.stop()
1084            return
1085        self._active_task = tasks.Task(
1086            target=main_presenter_async.check_for_cleaning,
1087            args=(
1088                tmp_protein_name,
1089                self._current_project,
1090            ),
1091            post_func=self.__await_check_for_cleaning,
1092        )
1093        self._active_task.start()
1094        self.update_status("Checking protein properties ...")
1095
1096    def __await_check_for_cleaning(self, result: tuple) -> None:
1097        # check if selected protein contains any organic or solvent molecules which can be removed
1098        tmp_is_cleanable: bool = result[1]
1099        tmp_is_in_protein_pair: bool = result[2]
1100        if tmp_is_cleanable:
1101            gui_elements_to_show = [
1102                self._view.ui.lbl_edit_clean_new_prot,
1103                self._view.ui.btn_edit_clean_new_prot,
1104                self._view.ui.lbl_edit_clean_update_prot,
1105                self._view.ui.btn_edit_clean_update_prot,
1106            ]
1107            gui_utils.show_gui_elements(gui_elements_to_show)
1108        else:
1109            gui_elements_to_hide = [
1110                self._view.ui.lbl_edit_clean_new_prot,
1111                self._view.ui.btn_edit_clean_new_prot,
1112                self._view.ui.lbl_edit_clean_update_prot,
1113                self._view.ui.btn_edit_clean_update_prot,
1114            ]
1115            gui_utils.hide_gui_elements(gui_elements_to_hide)
1116        # check if selected protein is in any existing protein pair
1117        if tmp_is_in_protein_pair:
1118            gui_elements_to_hide = [
1119                self._view.ui.label_12,
1120                self._view.ui.btn_edit_project_delete,
1121            ]
1122            gui_utils.hide_gui_elements(gui_elements_to_hide)
1123        else:
1124            gui_elements_to_show = [
1125                self._view.ui.label_12,
1126                self._view.ui.btn_edit_project_delete,
1127            ]
1128            gui_utils.show_gui_elements(gui_elements_to_show)
1129        self._view.ui.btn_edit_project_save.show()
1130        self._view.ui.label_13.show()
1131        self._view.ui.label_15.show()
1132        self._view.ui.btn_edit_protein_rename.show()
1133        self._view.ui.btn_manage_session.show()
1134        self._project_watcher.show_valid_options(self._view.ui)
1135        self._view.wait_spinner.stop()
1136        self.update_status(self._workspace_status)
1137
1138    def clean_protein_new(self) -> None:
1139        """Cleans the selected protein structure and creates a new cleaned structure."""
1140        self._view.wait_spinner.start()
1141        self._active_task = tasks.Task(
1142            target=main_presenter_async.clean_protein_new,
1143            args=(
1144                self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1145                self._current_project,
1146            ),
1147            post_func=self.__await_clean_protein_new,
1148        )
1149        self._active_task.start()
1150        self.update_status("Duplicating and cleaning protein ...")
1151
1152    def __await_clean_protein_new(self, result: tuple) -> None:
1153        self._init_edit_page()
1154        self._project_watcher.show_valid_options(self._view.ui)
1155        self._view.wait_spinner.stop()
1156        self.update_status(self._workspace_status)
1157
1158    def clean_protein_update(self) -> None:
1159        """Cleans the selected protein structure."""
1160        self._view.wait_spinner.start()
1161        if basic_boxes.yes_or_no(
1162            "Clean protein",
1163            "Are you sure you want to clean this protein?\n" "This will remove all organic and solvent components!",
1164            QtWidgets.QMessageBox.Information,
1165        ):
1166            self._active_task = tasks.Task(
1167                target=main_presenter_async.clean_protein_update,
1168                args=(
1169                    self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1170                    self._current_project,
1171                ),
1172                post_func=self.__await_clean_protein_update,
1173            )
1174            self._active_task.start()
1175            self.update_status("Cleaning protein ...")
1176        else:
1177            constants.PYSSA_LOGGER.info("No protein has been cleaned.")
1178            self._view.wait_spinner.stop()
1179
1180    def __await_clean_protein_update(self) -> None:
1181        self._init_edit_page()
1182        self._project_watcher.show_valid_options(self._view.ui)
1183        self._view.wait_spinner.stop()
1184        self.update_status(self._workspace_status)
1185
1186    def delete_protein(self) -> None:
1187        """Deletes the selected protein structure."""
1188        self._view.wait_spinner.start()
1189        if gui_utils.warning_message_protein_gets_deleted():
1190            self._active_task = tasks.Task(
1191                target=main_presenter_async.delete_protein,
1192                args=(
1193                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1194                    self._current_project,
1195                ),
1196                post_func=self.__await_delete_protein,
1197            )
1198            self._active_task.start()
1199            self.update_status("Deleting protein ...")
1200        else:
1201            constants.PYSSA_LOGGER.info("No protein was deleted.")
1202            self._view.wait_spinner.stop()
1203
1204    def __await_delete_protein(self) -> None:
1205        self._init_edit_page()
1206        self._project_watcher.show_valid_options(self._view.ui)
1207        self._view.wait_spinner.stop()
1208        self.update_status(self._workspace_status)
1209
1210    def add_existing_protein(self) -> None:
1211        """Opens a dialog to adds an existing protein structure to the project."""
1212        self.tmp_dialog = view_add_protein.AddProteinView()
1213        self.tmp_dialog.return_value.connect(self.post_add_existing_protein)
1214        self.tmp_dialog.show()
1215
1216    def post_add_existing_protein(self, return_value: tuple) -> None:
1217        """Adds an existing protein structure to the current project either by id or from the filesystem.
1218
1219        Args:
1220            return_value: a tuple consisting of the filepath or PDB id and the length of the first one.
1221        """
1222        self._view.wait_spinner.start()
1223        if return_value[1] > 0:
1224            self._active_task = tasks.Task(
1225                target=main_presenter_async.add_existing_protein_to_project,
1226                args=(return_value, self._current_project),
1227                post_func=self.__await_post_add_existing_protein,
1228            )
1229            self._active_task.start()
1230            self.update_status("Adding protein to current project ...")
1231        else:
1232            self._view.wait_spinner.stop()
1233            self.display_edit_page()
1234
1235    def __await_post_add_existing_protein(self, result: tuple) -> None:
1236        self._current_project = result[1]
1237        self._project_watcher.show_valid_options(self._view.ui)
1238        self._view.wait_spinner.stop()
1239        self.update_status(self._workspace_status)
1240        self.display_edit_page()
1241
1242    def save_selected_protein_structure_as_pdb_file(self) -> None:
1243        """Saves selected protein as pdb file."""
1244        self._view.wait_spinner.start()
1245        file_dialog = QtWidgets.QFileDialog()
1246        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1247        file_dialog.setDirectory(desktop_path)
1248        file_path, _ = file_dialog.getSaveFileName(
1249            self._view,
1250            "Save protein structure",
1251            "",
1252            "Protein Data Bank File (*.pdb)",
1253        )
1254        if file_path:
1255            self._active_task = tasks.Task(
1256                target=main_presenter_async.save_selected_protein_structure_as_pdb_file,
1257                args=(self._view.ui.list_edit_project_proteins.currentItem().text(), self._current_project, file_path),
1258                post_func=self.__await_save_selected_protein_structure_as_pdb_file,
1259            )
1260            self._active_task.start()
1261        else:
1262            self._view.wait_spinner.stop()
1263
1264    def __await_save_selected_protein_structure_as_pdb_file(self, result: tuple) -> None:
1265        self._view.wait_spinner.stop()
1266        if result[0] == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1267            basic_boxes.ok(
1268                "Save protein structure",
1269                "Saving the protein as .pdb file failed!",
1270                QtWidgets.QMessageBox.Error,
1271            )
1272        elif result[0] == exit_codes.EXIT_CODE_ZERO[0]:
1273            basic_boxes.ok(
1274                "Save protein structure",
1275                "The protein was successfully saved as .pdb file.",
1276                QtWidgets.QMessageBox.Information,
1277            )
1278        else:
1279            basic_boxes.ok(
1280                "Save protein structure",
1281                "Saving the protein as .pdb file failed with an unexpected error!",
1282                QtWidgets.QMessageBox.Error,
1283            )
1284        self._project_watcher.show_valid_options(self._view.ui)
1285        self.update_status(self._workspace_status)
1286
1287    def rename_selected_protein_structure(self) -> None:
1288        """Opens a new view to rename the selected protein."""
1289        self._view.wait_spinner.start()
1290        self.tmp_dialog = dialog_rename_protein.DialogRenameProtein(self._workspace_path)
1291        self.tmp_dialog.return_value.connect(self.post_rename_selected_protein_structure)
1292        self.tmp_dialog.show()
1293
1294    def post_rename_selected_protein_structure(self, return_value: tuple) -> None:
1295        """Renames a selected protein structure."""
1296        if return_value[1] is True:
1297            self._active_task = tasks.Task(
1298                target=main_presenter_async.rename_selected_protein_structure,
1299                args=(
1300                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1301                    return_value[0],
1302                    self._current_project,
1303                ),
1304                post_func=self.__await_post_rename_selected_protein_structure,
1305            )
1306            self._active_task.start()
1307        else:
1308            self._view.wait_spinner.stop()
1309
1310    def __await_post_rename_selected_protein_structure(self, result: tuple) -> None:
1311        self._init_edit_page()
1312        self._project_watcher.show_valid_options(self._view.ui)
1313        self._view.wait_spinner.stop()
1314
1315    # </editor-fold>
1316
1317    # <editor-fold desc="View project page functions">
1318    def view_structure(self) -> None:
1319        """Displays the structure of the selected protein in pymol."""
1320        protein_name = self._view.ui.list_view_project_proteins.currentItem().text()
1321        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1322        cmd.reinitialize()
1323        self._view.ui.btn_manage_session.show()
1324        try:
1325            self._current_project.search_protein(protein_name).load_protein_pymol_session()
1326            constants.PYSSA_LOGGER.info("Loaded PyMOL session of protein %s", protein_name)
1327        except pymol.CmdException:
1328            constants.PYSSA_LOGGER.error("Error while loading protein in PyMOL!")
1329            return
1330        self.current_session = current_session.CurrentSession(
1331            "protein",
1332            protein_name,
1333            self._current_project.search_protein(protein_name).pymol_session,
1334        )
1335        print(self.current_session)
1336
1337    # </editor-fold>
1338
1339    # <editor-fold desc="Use project page functions">
1340    def display_use_page(self) -> None:
1341        """Displays the use project page."""
1342        self._view.wait_spinner.start()
1343        if self.is_distance_plot_open:
1344            self.distance_plot_dialog.close()
1345            self.is_distance_plot_open = False
1346
1347        self.start_worker_thread(
1348            task_workers.LoadUsePageWorker(
1349                self._workspace_path,
1350                self._current_project.convert_list_of_proteins_to_list_of_protein_infos(),
1351            ),
1352            self.post_display_use_page,
1353        )
1354        self._init_use_page()
1355
1356    def post_display_use_page(self, return_value) -> None:  # noqa: ANN001
1357        """Displays the use project page, after cpu intense task (post thread method).
1358
1359        Args:
1360            return_value: the value which gets returned from the thread process
1361        """
1362        # this for-loop is necessary for eliminating all proteins which are in the current project from the ones which
1363        # are available
1364        for tmp_item in return_value[0]:
1365            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1366        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1367            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1368            tmp_prot_name = self._view.ui.list_use_selected_protein_structures.currentItem().text()
1369            if tmp_prot_name in return_value[1]:
1370                return_value[1].remove(tmp_prot_name)
1371
1372        for tmp_item in return_value[1]:
1373            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1374        for tmp_project_name in return_value[2]:
1375            self._view.ui.list_use_existing_projects.addItem(QtWidgets.QListWidgetItem(tmp_project_name))
1376
1377        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 14, "Use existing project")
1378        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_use_page)
1379        self._view.wait_spinner.stop()
1380
1381    def pre_create_use_project(self) -> None:
1382        """Sets up the worker for the create_use_project task."""
1383        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
1384        # copy proteins in new project
1385        proteins_to_copy = []
1386        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1387            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1388            proteins_to_copy.append(self._view.ui.list_use_selected_protein_structures.currentItem().text())
1389
1390        # <editor-fold desc="Worker setup">
1391        # --Begin: worker setup
1392        self.tmp_thread = QtCore.QThread()
1393        self.tmp_worker = task_workers.CreateUseProjectWorker(self._workspace_path, proteins_to_copy)
1394        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.create_use_project)
1395        self.tmp_thread.start()
1396        # --End: worker setup
1397
1398        # </editor-fold>
1399
1400        self._view.ui.lbl_current_project_name.setText(self._view.ui.txt_use_project_name.text())
1401        self._view.status_bar.showMessage(f"Creating new project: {self._view.ui.txt_use_project_name.text()} ...")
1402        # save project folder in current workspace
1403        new_project = project.Project(self._view.ui.txt_use_project_name.text(), self._workspace_path)
1404        # new_project.create_project_tree()
1405        self._current_project = new_project
1406
1407    def create_use_project(self, proteins_for_new_project) -> None:  # noqa: ANN001
1408        """Post thread method.
1409
1410        Args:
1411            proteins_for_new_project (list): the proteins which are in the new project
1412        """
1413        for tmp_protein_obj in proteins_for_new_project:
1414            self._current_project.add_existing_protein(tmp_protein_obj)
1415        self._current_project.serialize_project(
1416            pathlib.Path(f"{self._workspace_path}/{self._current_project.get_project_name()}.xml"),
1417        )
1418        # shows options which can be done with the data in the project folder
1419        self._project_watcher.current_project = self._current_project
1420        self._project_watcher.on_home_page = False
1421        self._project_watcher.show_valid_options(self._view.ui)
1422        self.project_scanner.project = self._current_project
1423        self._init_use_page()
1424        constants.PYSSA_LOGGER.info(
1425            f"The project {self._current_project.get_project_name()} was successfully created through a use.",
1426        )
1427        self.display_view_page()
1428        QtWidgets.QApplication.restoreOverrideCursor()
1429
1430    # </editor-fold>
1431
1432    # <editor-fold desc="Import, Export functions">
1433    def import_project(self) -> None:
1434        """Imports a project.xml into the current workspace."""
1435        self.last_sidebar_button = styles.color_sidebar_buttons(
1436            self.last_sidebar_button,
1437            self._view.ui.btn_import_project,
1438        )
1439        file_dialog = QtWidgets.QFileDialog()
1440        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1441        file_dialog.setDirectory(desktop_path)
1442        file_path, _ = file_dialog.getOpenFileName(
1443            self._view,
1444            "Select a project file to import",
1445            "",
1446            "XML Files (*.xml)",
1447        )
1448        if file_path:
1449            tmp_project = project.Project("", self._workspace_path)
1450            tmp_project = tmp_project.deserialize_project(pathlib.Path(file_path), self._application_settings)
1451            tmp_project.set_workspace_path(self._workspace_path)
1452            if len(tmp_project.proteins) <= 1:
1453                if self._application_settings.wsl_install == 0:
1454                    basic_boxes.ok(
1455                        "Create new project",
1456                        "Please install local colabfold to import this project!",
1457                        QtWidgets.QMessageBox.Warning,
1458                    )
1459                    return
1460                elif self._application_settings.local_colabfold == 0:  # noqa: RET505
1461                    basic_boxes.ok(
1462                        "Create new project",
1463                        "Please install local colabfold to import this project!",
1464                        QtWidgets.QMessageBox.Warning,
1465                    )
1466                    return
1467            new_filepath = pathlib.Path(f"{self._workspace_path}/{tmp_project.get_project_name()}.xml")
1468            tmp_project.serialize_project(new_filepath)
1469            self._current_project = self._current_project.deserialize_project(new_filepath, self._application_settings)
1470            constants.PYSSA_LOGGER.info(f"Opening the project {self._current_project.get_project_name()}.")
1471            self._project_watcher.current_project = self._current_project
1472            self.project_scanner.project = self._current_project
1473            constants.PYSSA_LOGGER.info(
1474                f"{self._project_watcher.current_project.get_project_name()} is the current project.",
1475            )
1476            self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
1477            self._project_watcher.on_home_page = False
1478            self._project_watcher.show_valid_options(self._view.ui)
1479            self._view.ui.btn_manage_session.show()
1480            self.display_view_page()
1481            basic_boxes.ok(
1482                "Import Project",
1483                "The project was successfully imported.",
1484                QtWidgets.QMessageBox.Information,
1485            )
1486
1487    def export_current_project(self) -> None:
1488        """Exports the current project to an importable format."""
1489        if self.is_distance_plot_open:
1490            self.distance_plot_dialog.close()
1491            self.is_distance_plot_open = False
1492        self.last_sidebar_button = styles.color_sidebar_buttons(
1493            self.last_sidebar_button,
1494            self._view.ui.btn_export_project,
1495        )
1496        file_dialog = QtWidgets.QFileDialog()
1497        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1498        file_dialog.setDirectory(desktop_path)
1499        file_path, _ = file_dialog.getSaveFileName(self._view, "Save current project", "", "XML Files (*.xml)")
1500        if file_path:
1501            self._current_project.serialize_project(pathlib.Path(file_path))
1502            basic_boxes.ok(
1503                "Export Project",
1504                "The project was successfully exported.",
1505                QtWidgets.QMessageBox.Information,
1506            )
1507
1508    # </editor-fold>
1509
1510    # <editor-fold desc="Close project functions">
1511    def close_project(self) -> None:
1512        """Closes the current project."""
1513        if self.is_distance_plot_open:
1514            self.distance_plot_dialog.close()
1515            self.is_distance_plot_open = False
1516        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1517        cmd.reinitialize()
1518        self._view.ui.list_hotspots_choose_protein.clear()
1519        self._project_watcher.on_home_page = True
1520        self._project_watcher.current_project = project.Project("", pathlib.Path(""))
1521        self._project_watcher.show_valid_options(self._view.ui)
1522        self._view.ui.lbl_current_project_name.setText("")
1523        self._init_all_pages()
1524        self.results_name = ""
1525        constants.PYSSA_LOGGER.info(f"The project {self._current_project.get_project_name()} was closed")
1526        self.display_home_page()
1527
1528    # </editor-fold>
1529
1530    # <editor-fold desc="ESMFold Monomer functions">
1531    def post_predict_esm_monomer(self, output) -> None:  # noqa: ANN001
1532        """Post thread method, for the prediction process.
1533
1534        Args:
1535            output (list): the proteins which got predicted
1536        """
1537        self.block_box_prediction.destroy(True)
1538        for tmp_filename in os.listdir(constants.ESMFOLD_PDB_DIR):
1539            constants.PYSSA_LOGGER.info(
1540                f"Add protein {tmp_filename} to the current project {self._current_project.get_project_name()}",
1541            )
1542            self._current_project.add_existing_protein(
1543                protein.Protein(
1544                    tmp_filename.replace(".pdb", ""),
1545                    path_util.FilePath(pathlib.Path(f"{constants.ESMFOLD_PDB_DIR}/{tmp_filename}")),
1546                ),
1547            )
1548        if len(output) > 0:
1549            formatted_output = ", ".join(output)
1550            basic_boxes.ok(
1551                "ESMFold Prediction",
1552                f"These protein prediction failed: {formatted_output}.",
1553                QtWidgets.QMessageBox.Critical,
1554            )
1555        else:
1556            basic_boxes.ok("ESMFold Prediction", "The prediction was successful.", QtWidgets.QMessageBox.Information)
1557        self._current_project.serialize_project(self._current_project.get_project_xml_path())
1558        self.display_view_page()
1559        self._project_watcher.show_valid_options(self._view.ui)
1560
1561    def predict_esm_monomer(self) -> None:
1562        """Sets up the worker to predict the proteins with the ESM-Fold."""
1563        # <editor-fold desc="Worker setup">
1564        # --Begin: worker setup
1565        self.tmp_thread = QtCore.QThread()
1566        self.tmp_worker = task_workers.EsmFoldWorker(self._view.ui.table_esm_prot_to_predict)
1567        self.tmp_thread = task_workers.setup_worker_for_work(
1568            self.tmp_thread,
1569            self.tmp_worker,
1570            self.post_predict_esm_monomer,
1571        )
1572        self.tmp_thread.start()
1573        # --End: worker setup
1574
1575        # </editor-fold>
1576
1577        self.block_box_prediction = QtWidgets.QMessageBox()
1578        self.block_box_prediction = gui_utils.setup_standard_block_box(
1579            self.block_box_prediction,
1580            "Structure Prediction",
1581            "A prediction is currently running.",
1582        )
1583        # self.block_box_prediction.setStandardButtons(QtWidgets.QMessageBox.NoButton)
1584        # self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1585        # self.block_box_prediction.setWindowIcon(
1586        #     PyQt5.constants.PLUGIN_LOGO_ICON_OBJ)
1587        # styles.set_stylesheet(self.block_box_prediction)
1588        # self.block_box_prediction.setWindowTitle("Structure Prediction")
1589        # self.block_box_prediction.setText("A prediction is currently running.")
1590        self.block_box_prediction.exec_()
1591
1592    # </editor-fold>
1593
1594    # <editor-fold desc="Monomer Local Prediction functions">
1595    def post_prediction_process(self, an_exit_code: int, an_exit_code_description: str) -> None:
1596        """Process which runs after each prediction job."""
1597        if an_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1598            self.block_box_prediction.destroy(True)
1599            basic_boxes.ok(
1600                "Prediction",
1601                "Prediction failed because there was an error writing the fasta file(s)!",
1602                QtWidgets.QMessageBox.Critical,
1603            )
1604            self.display_view_page()
1605            self._project_watcher.show_valid_options(self._view.ui)
1606            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1607        elif an_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
1608            self.block_box_prediction.destroy(True)
1609            basic_boxes.ok(
1610                "Prediction",
1611                "Prediction failed because the fasta file(s) could not be found!",
1612                QtWidgets.QMessageBox.Critical,
1613            )
1614            self.display_view_page()
1615            self._project_watcher.show_valid_options(self._view.ui)
1616            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1617        elif an_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
1618            self.block_box_prediction.destroy(True)
1619            basic_boxes.ok(
1620                "Prediction",
1621                "Prediction failed because a subprocess failed!",
1622                QtWidgets.QMessageBox.Critical,
1623            )
1624            self.display_view_page()
1625            self._project_watcher.show_valid_options(self._view.ui)
1626            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1627        elif an_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1628            self.block_box_prediction.destroy(True)
1629            basic_boxes.ok(
1630                "Prediction",
1631                "Prediction failed because of an unknown error!",
1632                QtWidgets.QMessageBox.Critical,
1633            )
1634            self.display_view_page()
1635            self._project_watcher.show_valid_options(self._view.ui)
1636            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1637        elif an_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1638            # Prediction was successful
1639            if self.prediction_type == constants.PREDICTION_TYPE_PRED:
1640                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1641                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1642                self.block_box_prediction.destroy(True)
1643                basic_boxes.ok(
1644                    "Structure prediction",
1645                    "All structure predictions are done. Go to View to check the new proteins.",
1646                    QtWidgets.QMessageBox.Information,
1647                )
1648                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1649                self._project_watcher.show_valid_options(self._view.ui)
1650                self._init_local_pred_mono_page()
1651                self._init_local_pred_multi_page()
1652                self.display_view_page()
1653            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS:
1654                # executes if monomers were successfully predicted
1655                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1656                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1657                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1658                constants.PYSSA_LOGGER.info("Begin analysis process.")
1659                constants.PYSSA_LOGGER.debug(
1660                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1661                )
1662
1663                # self.worker_analysis = workers.AnalysisWorkerPool(
1664                #    self._view.ui.list_pred_analysis_mono_overview, self._view.ui.cb_pred_analysis_mono_images,
1665                #    self._view.status_bar, self._current_project, self._application_settings, self._init_mono_pred_analysis_page)
1666                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1667                # self.threadpool.start(self.worker_analysis)
1668                constants.PYSSA_LOGGER.debug(
1669                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1670                )
1671
1672                # <editor-fold desc="Worker setup">
1673                # TODO: test code below
1674                # --Begin: worker setup
1675                self.tmp_thread = QtCore.QThread()
1676                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1677                    self._view.ui.list_pred_analysis_mono_overview,
1678                    self._view.ui.cb_pred_analysis_mono_images,
1679                    self._view.status_bar,
1680                    self._current_project,
1681                    self._application_settings,
1682                    self._init_mono_pred_analysis_page,
1683                )
1684                self.tmp_thread = task_workers.setup_worker_for_work(
1685                    self.tmp_thread,
1686                    self.tmp_worker,
1687                    self.display_view_page,
1688                )
1689                self.tmp_worker.finished.connect(self.post_analysis_process)
1690                self.tmp_thread.start()
1691                # --End: worker setup
1692
1693                # </editor-fold>
1694
1695                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1696                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1697                self.block_box_prediction.destroy(True)
1698                self.block_box_analysis.exec_()
1699                self.display_view_page()
1700                self._project_watcher.show_valid_options(self._view.ui)
1701            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS:
1702                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1703                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1704                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1705                constants.PYSSA_LOGGER.info("Begin analysis process.")
1706                constants.PYSSA_LOGGER.debug(
1707                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1708                )
1709
1710                # self.worker_analysis = workers.AnalysisWorkerPool(
1711                #    self._view.ui.list_pred_analysis_multi_overview, self._view.ui.cb_pred_analysis_multi_images,
1712                #    self._view.status_bar, self._current_project, self._application_settings, self._init_multi_pred_analysis_page)
1713                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1714                # self.threadpool.start(self.worker_analysis)
1715                constants.PYSSA_LOGGER.debug(
1716                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1717                )
1718
1719                # <editor-fold desc="Worker setup">
1720                # TODO: test code below
1721                # --Begin: worker setup
1722                self.tmp_thread = QtCore.QThread()
1723                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1724                    self._view.ui.list_pred_analysis_multi_overview,
1725                    self._view.ui.cb_pred_analysis_multi_images,
1726                    self._view.status_bar,
1727                    self._current_project,
1728                    self._application_settings,
1729                    self._init_multi_pred_analysis_page,
1730                )
1731                self.tmp_thread = task_workers.setup_worker_for_work(
1732                    self.tmp_thread,
1733                    self.tmp_worker,
1734                    self.display_view_page,
1735                )
1736                self.tmp_worker.finished.connect(self.post_analysis_process)
1737                self.tmp_thread.start()
1738                # --End: worker setup
1739
1740                # </editor-fold>
1741
1742                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1743                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1744                self.block_box_prediction.destroy(True)
1745                self.block_box_analysis.exec_()
1746                self.display_view_page()
1747                self._project_watcher.show_valid_options(self._view.ui)
1748        try:
1749            shutil.rmtree(pathlib.Path(f"{constants.SCRATCH_DIR}/local_predictions"))
1750        except Exception as e:
1751            constants.PYSSA_LOGGER.warning(f"Local predictions scratch path could not be deleted. {e}")
1752
1753    def predict_local_monomer(self) -> None:
1754        """Sets tup the worker for the prediction with the colabfold."""
1755        self._view.wait_spinner.start()
1756        self.prediction_type = constants.PREDICTION_TYPE_PRED
1757        constants.PYSSA_LOGGER.info("Begin prediction process.")
1758        self.update_status("Begin prediction process ...")
1759        predictions: list[
1760            prediction_protein_info.PredictionProteinInfo
1761        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_mono_prot_to_predict)
1762
1763        self._active_task = tasks.Task(
1764            target=main_presenter_async.predict_protein_with_colabfold,
1765            args=(
1766                predictions,
1767                self.prediction_configuration,
1768                self._current_project,
1769            ),
1770            post_func=self.__await_predict_protein_with_colabfold,
1771        )
1772        self._active_task.start()
1773
1774        self.block_box_prediction = QtWidgets.QMessageBox()
1775        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1776        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1777        styles.set_stylesheet(self.block_box_prediction)
1778        self.block_box_prediction.setWindowTitle("Structure Prediction")
1779        self.block_box_prediction.setText("A prediction is currently running.")
1780        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1781        self.block_box_prediction.exec_()
1782        if self.block_box_prediction.clickedButton() == btn_abort:
1783            self.abort_prediction()
1784            self.block_box_prediction.close()
1785            self._view.wait_spinner.stop()
1786            return
1787        else:  # noqa: RET505
1788            self.block_box_prediction.close()
1789            self._view.wait_spinner.stop()
1790
1791    def __await_predict_protein_with_colabfold(self, result: tuple) -> None:
1792        """Process which runs after each prediction job."""
1793        tmp_exit_code = result[0]
1794        tmp_exit_code_description = [1]
1795        if tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1796            self.block_box_prediction.destroy(True)
1797            basic_boxes.ok(
1798                "Prediction",
1799                "Prediction failed because there was an error writing the fasta file(s)!",
1800                QtWidgets.QMessageBox.Critical,
1801            )
1802            self.display_view_page()
1803            self._project_watcher.show_valid_options(self._view.ui)
1804            constants.PYSSA_LOGGER.error(
1805                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1806            )
1807        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
1808            self.block_box_prediction.destroy(True)
1809            basic_boxes.ok(
1810                "Prediction",
1811                "Prediction failed because the fasta file(s) could not be found!",
1812                QtWidgets.QMessageBox.Critical,
1813            )
1814            self.display_view_page()
1815            self._project_watcher.show_valid_options(self._view.ui)
1816            constants.PYSSA_LOGGER.error(
1817                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1818            )
1819        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
1820            self.block_box_prediction.destroy(True)
1821            basic_boxes.ok(
1822                "Prediction",
1823                "Prediction failed because a subprocess failed!",
1824                QtWidgets.QMessageBox.Critical,
1825            )
1826            self.display_view_page()
1827            self._project_watcher.show_valid_options(self._view.ui)
1828            constants.PYSSA_LOGGER.error(
1829                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1830            )
1831        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1832            self.block_box_prediction.destroy(True)
1833            basic_boxes.ok(
1834                "Prediction",
1835                "Prediction failed because of an unknown error!",
1836                QtWidgets.QMessageBox.Critical,
1837            )
1838            self.display_view_page()
1839            self._project_watcher.show_valid_options(self._view.ui)
1840            constants.PYSSA_LOGGER.error(
1841                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
1842            )
1843        elif tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1844            # Prediction was successful
1845            if self.prediction_type == constants.PREDICTION_TYPE_PRED:
1846                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1847                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1848                self.block_box_prediction.destroy(True)
1849                basic_boxes.ok(
1850                    "Structure prediction",
1851                    "All structure predictions are done. Go to View to check the new proteins.",
1852                    QtWidgets.QMessageBox.Information,
1853                )
1854                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1855                self._project_watcher.show_valid_options(self._view.ui)
1856                self._init_local_pred_mono_page()
1857                self._init_local_pred_multi_page()
1858                self.display_view_page()
1859        self._view.wait_spinner.stop()
1860
1861    def abort_prediction(self) -> None:
1862        """Aborts the running prediction."""
1863        constants.PYSSA_LOGGER.info("Structure prediction process was aborted manually.")
1864        subprocess.run(["wsl", "--shutdown"])
1865        constants.PYSSA_LOGGER.info("Shutdown of wsl environment.")
1866        filesystem_io.FilesystemCleaner.clean_prediction_scratch_folder()
1867        constants.PYSSA_LOGGER.info("Cleaned scratch directory.")
1868        basic_boxes.ok("Abort prediction", "The structure prediction was aborted.", QtWidgets.QMessageBox.Information)
1869        self.last_sidebar_button = styles.color_sidebar_buttons(
1870            self.last_sidebar_button,
1871            self._view.ui.btn_prediction_abort,
1872        )
1873        self._project_watcher.show_valid_options(self._view.ui)
1874
1875    # </editor-fold>
1876
1877    # <editor-fold desc="Multimer Local Prediction functions">
1878    def predict_local_multimer(self) -> None:
1879        """Sets up the worker for the prediction with the colabfold."""
1880        self._view.wait_spinner.start()
1881        self.prediction_type = constants.PREDICTION_TYPE_PRED
1882        constants.PYSSA_LOGGER.info("Begin multimer prediction process.")
1883        self.update_status("Begin prediction process ...")
1884        predictions: list[
1885            prediction_protein_info.PredictionProteinInfo
1886        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_multi_prot_to_predict)
1887
1888        self._active_task = tasks.Task(
1889            target=main_presenter_async.predict_protein_with_colabfold,
1890            args=(
1891                predictions,
1892                self.prediction_configuration,
1893                self._current_project,
1894            ),
1895            post_func=self.__await_predict_protein_with_colabfold,
1896        )
1897        self._active_task.start()
1898
1899        self.block_box_prediction = QtWidgets.QMessageBox()
1900        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1901        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1902        styles.set_stylesheet(self.block_box_prediction)
1903        self.block_box_prediction.setWindowTitle("Structure Prediction")
1904        self.block_box_prediction.setText("A prediction is currently running.")
1905        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1906        self.block_box_prediction.exec_()
1907        if self.block_box_prediction.clickedButton() == btn_abort:
1908            self.abort_prediction()
1909            self.block_box_prediction.close()
1910            self._view.wait_spinner.stop()
1911        else:
1912            self.block_box_prediction.close()
1913            self._view.wait_spinner.stop()
1914
1915    # </editor-fold>
1916
1917    # <editor-fold desc="Monomer Prediction + Analysis functions">
1918    def start_monomer_prediction_analysis(self) -> None:
1919        """Sets up the worker for the prediction of the proteins."""
1920        self._view.wait_spinner.start()
1921        self.prediction_type = constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS
1922        constants.PYSSA_LOGGER.info("Begin prediction process.")
1923        self.update_status("Begin prediction process ...")
1924        predictions: list[
1925            prediction_protein_info.PredictionProteinInfo
1926        ] = prediction_util.get_prediction_name_and_seq_from_table(
1927            self._view.ui.table_pred_analysis_mono_prot_to_predict,
1928        )
1929
1930        self._active_task = tasks.Task(
1931            target=main_presenter_async.predict_protein_with_colabfold,
1932            args=(
1933                predictions,
1934                self.prediction_configuration,
1935                self._current_project,
1936            ),
1937            post_func=self.__await_monomer_prediction_for_subsequent_analysis,
1938        )
1939        self._active_task.start()
1940
1941        self.block_box_prediction = QtWidgets.QMessageBox()
1942        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1943        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1944        styles.set_stylesheet(self.block_box_prediction)
1945        self.block_box_prediction.setWindowTitle("Structure Prediction")
1946        self.block_box_prediction.setText("A prediction is currently running.")
1947        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1948        self.block_box_prediction.exec_()
1949        if self.block_box_prediction.clickedButton() == btn_abort:
1950            self.abort_prediction()
1951            self.block_box_prediction.close()
1952            self._view.wait_spinner.stop()
1953        else:
1954            self.block_box_prediction.close()
1955            self._view.wait_spinner.stop()
1956
1957    def __await_monomer_prediction_for_subsequent_analysis(self, result: tuple) -> None:
1958        tmp_exit_code = result[0]
1959        tmp_exit_code_description = [1]
1960        if tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1961            # Prediction was successful
1962            self.block_box_prediction.destroy(True)
1963            constants.PYSSA_LOGGER.info("All structure predictions are done.")
1964            self.update_status("All structure predictions are done.")
1965            constants.PYSSA_LOGGER.info("Begin analysis process.")
1966            self.update_status("Begin analysis process ...")
1967
1968            tmp_raw_analysis_run_names: list = []
1969            for row_no in range(self._view.ui.list_pred_analysis_mono_overview.count()):
1970                tmp_raw_analysis_run_names.append(self._view.ui.list_pred_analysis_mono_overview.item(row_no).text())
1971
1972            self._active_task = tasks.Task(
1973                target=main_presenter_async.run_distance_analysis,
1974                args=(
1975                    tmp_raw_analysis_run_names,
1976                    self._current_project,
1977                    self._application_settings,
1978                    self._view.ui.cb_pred_analysis_mono_images.isChecked(),
1979                ),
1980                post_func=self.post_analysis_process,
1981            )
1982            self._active_task.start()
1983
1984            if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1985                os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1986            self.block_box_analysis.exec_()
1987            self.display_view_page()
1988
1989        elif tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1990            self.block_box_prediction.destroy(True)
1991            basic_boxes.ok(
1992                "Prediction",
1993                "Prediction failed because there was an error writing the fasta file(s)!",
1994                QtWidgets.QMessageBox.Critical,
1995            )
1996            self.display_view_page()
1997            self._project_watcher.show_valid_options(self._view.ui)
1998            constants.PYSSA_LOGGER.error(
1999                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2000            )
2001            self._view.wait_spinner.stop()
2002        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
2003            self.block_box_prediction.destroy(True)
2004            basic_boxes.ok(
2005                "Prediction",
2006                "Prediction failed because the fasta file(s) could not be found!",
2007                QtWidgets.QMessageBox.Critical,
2008            )
2009            self.display_view_page()
2010            self._project_watcher.show_valid_options(self._view.ui)
2011            constants.PYSSA_LOGGER.error(
2012                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2013            )
2014            self._view.wait_spinner.stop()
2015        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
2016            self.block_box_prediction.destroy(True)
2017            basic_boxes.ok(
2018                "Prediction",
2019                "Prediction failed because a subprocess failed!",
2020                QtWidgets.QMessageBox.Critical,
2021            )
2022            self.display_view_page()
2023            self._project_watcher.show_valid_options(self._view.ui)
2024            constants.PYSSA_LOGGER.error(
2025                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2026            )
2027            self._view.wait_spinner.stop()
2028        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2029            self.block_box_prediction.destroy(True)
2030            basic_boxes.ok(
2031                "Prediction",
2032                "Prediction failed because of an unknown error!",
2033                QtWidgets.QMessageBox.Critical,
2034            )
2035            self.display_view_page()
2036            self._project_watcher.show_valid_options(self._view.ui)
2037            constants.PYSSA_LOGGER.error(
2038                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2039            )
2040            self._view.wait_spinner.stop()
2041
2042    def mono_pred_analysis_structure_analysis_next_2(self) -> None:
2043        """Shows the gui elements for the chain selection of protein 1."""
2044        self._view.wait_spinner.start()
2045        tmp_proteins_to_predict: list[str] = []
2046        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
2047            tmp_proteins_to_predict.append(
2048                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text(),
2049            )
2050        self._active_task = tasks.Task(
2051            target=main_presenter_async.check_chains_for_subsequent_analysis,
2052            args=(
2053                self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2054                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
2055                self._current_project,
2056                tmp_proteins_to_predict,
2057            ),
2058            post_func=self.__await_mono_pred_analysis_structure_analysis_next_2,
2059        )
2060        self._active_task.start()
2061
2062    def __await_mono_pred_analysis_structure_analysis_next_2(self, result: tuple) -> None:
2063        _, tmp_analysis_name = result
2064        if tmp_analysis_name != "":
2065            gui_elements_to_show = [
2066                self._view.ui.btn_pred_analysis_mono_remove,
2067                self._view.ui.btn_pred_analysis_mono_add,
2068                self._view.ui.lbl_pred_analysis_mono_overview,
2069                self._view.ui.list_pred_analysis_mono_overview,
2070                self._view.ui.lbl_pred_analysis_mono_images,
2071                self._view.ui.cb_pred_analysis_mono_images,
2072                self._view.ui.btn_pred_analysis_mono_start,
2073                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
2074            ]
2075            gui_elements_to_hide = [
2076                self._view.ui.box_pred_analysis_mono_prot_struct_1,
2077                self._view.ui.box_pred_analysis_mono_prot_struct_2,
2078                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
2079                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
2080                self._view.ui.lbl_analysis_batch_vs_2,
2081                self._view.ui.lbl_pred_analysis_mono_ref_chains,
2082                self._view.ui.list_pred_analysis_mono_ref_chains,
2083                self._view.ui.lbl_pred_analysis_mono_model_chains,
2084                self._view.ui.list_pred_analysis_mono_model_chains,
2085                self._view.ui.btn_pred_analysis_mono_back_3,
2086                self._view.ui.btn_pred_analysis_mono_next_2,
2087                self._view.ui.btn_pred_analysis_mono_back_4,
2088                self._view.ui.btn_pred_analysis_mono_next_3,
2089                self._view.ui.btn_pred_analysis_mono_back_5,
2090                self._view.ui.btn_pred_analysis_mono_next_4,
2091            ]
2092            gui_utils.show_gui_elements(gui_elements_to_show)
2093            gui_utils.hide_gui_elements(gui_elements_to_hide)
2094            item = QtWidgets.QListWidgetItem(tmp_analysis_name)
2095            self._view.ui.list_pred_analysis_mono_overview.addItem(item)
2096            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
2097        else:
2098            gui_elements_to_show = [
2099                self._view.ui.lbl_pred_analysis_mono_overview,
2100                self._view.ui.list_pred_analysis_mono_overview,
2101                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
2102                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
2103                self._view.ui.lbl_analysis_batch_vs_2,
2104                self._view.ui.lbl_pred_analysis_mono_ref_chains,
2105                self._view.ui.list_pred_analysis_mono_ref_chains,
2106                self._view.ui.btn_pred_analysis_mono_back_4,
2107                self._view.ui.btn_pred_analysis_mono_next_3,
2108            ]
2109            gui_elements_to_hide = [
2110                self._view.ui.btn_pred_analysis_mono_remove,
2111                self._view.ui.btn_pred_analysis_mono_add,
2112                self._view.ui.box_pred_analysis_mono_prot_struct_1,
2113                self._view.ui.box_pred_analysis_mono_prot_struct_2,
2114                self._view.ui.btn_pred_analysis_mono_back_3,
2115                self._view.ui.btn_pred_analysis_mono_next_2,
2116                self._view.ui.lbl_pred_analysis_mono_model_chains,
2117                self._view.ui.list_pred_analysis_mono_model_chains,
2118                self._view.ui.btn_pred_analysis_mono_back_5,
2119                self._view.ui.btn_pred_analysis_mono_next_4,
2120                self._view.ui.lbl_pred_analysis_mono_images,
2121                self._view.ui.cb_pred_analysis_mono_images,
2122                self._view.ui.btn_pred_analysis_mono_start,
2123                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
2124            ]
2125            gui_utils.show_gui_elements(gui_elements_to_show)
2126            gui_utils.hide_gui_elements(gui_elements_to_hide)
2127            self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText(
2128                self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2129            )
2130            self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText(
2131                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
2132            )
2133            self._view.ui.list_pred_analysis_mono_ref_chains.clear()
2134            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(False)
2135            self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(True)
2136
2137            for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
2138                if (
2139                    self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text()
2140                    == self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText()
2141                ):
2142                    self._view.ui.list_pred_analysis_mono_ref_chains.addItem(
2143                        self._view.ui.table_pred_analysis_mono_prot_to_predict.item(i, 0).text(),
2144                    )
2145            if self._view.ui.list_pred_analysis_mono_ref_chains.count() == 0:
2146                tmp_protein = self._current_project.search_protein(
2147                    self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2148                )
2149                for tmp_chain in tmp_protein.chains:
2150                    if tmp_chain.chain_type == "protein_chain":
2151                        self._view.ui.list_pred_analysis_mono_ref_chains.addItem(tmp_chain.chain_letter)
2152            if self._view.ui.list_pred_analysis_mono_ref_chains.count() == 1:
2153                self._view.ui.lbl_pred_analysis_mono_ref_chains.setText(
2154                    f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()}.",
2155                )
2156            else:
2157                self._view.ui.lbl_pred_analysis_mono_ref_chains.setText(
2158                    f"Select chains in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()}.",
2159                )
2160        self._view.wait_spinner.stop()
2161
2162    # </editor-fold>
2163
2164    # <editor-fold desc="Multimer Prediction + Analysis functions">
2165    def start_multimer_prediction_analysis(self) -> None:
2166        """Sets up the prediction process."""
2167        self._view.wait_spinner.start()
2168        self.prediction_type = constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS
2169        constants.PYSSA_LOGGER.info("Begin prediction process.")
2170        self.update_status("Begin prediction process ...")
2171        predictions: list[
2172            prediction_protein_info.PredictionProteinInfo
2173        ] = prediction_util.get_prediction_name_and_seq_from_table(
2174            self._view.ui.table_pred_analysis_multi_prot_to_predict,
2175        )
2176
2177        self._active_task = tasks.Task(
2178            target=main_presenter_async.predict_protein_with_colabfold,
2179            args=(
2180                predictions,
2181                self.prediction_configuration,
2182                self._current_project,
2183            ),
2184            post_func=self.__await_multimer_prediction_for_subsequent_analysis,
2185        )
2186        self._active_task.start()
2187
2188        self.block_box_prediction = QtWidgets.QMessageBox()
2189        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
2190        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
2191        styles.set_stylesheet(self.block_box_prediction)
2192        self.block_box_prediction.setWindowTitle("Structure Prediction")
2193        self.block_box_prediction.setText("A prediction is currently running.")
2194        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
2195        self.block_box_prediction.exec_()
2196        if self.block_box_prediction.clickedButton() == btn_abort:
2197            self.abort_prediction()
2198            self.block_box_prediction.close()
2199            self._view.wait_spinner.stop()
2200        else:
2201            self.block_box_prediction.close()
2202            self._view.wait_spinner.stop()
2203
2204    def __await_multimer_prediction_for_subsequent_analysis(self, result: tuple) -> None:
2205        tmp_exit_code = result[0]
2206        tmp_exit_code_description = [1]
2207        if tmp_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
2208            # Prediction was successful
2209            self.block_box_prediction.destroy(True)
2210            constants.PYSSA_LOGGER.info("All structure predictions are done.")
2211            self.update_status("All structure predictions are done.")
2212            constants.PYSSA_LOGGER.info("Begin analysis process.")
2213            self.update_status("Begin analysis process ...")
2214            tmp_raw_analysis_run_names: list = []
2215            for row_no in range(self._view.ui.list_pred_analysis_multi_overview.count()):
2216                tmp_raw_analysis_run_names.append(self._view.ui.list_pred_analysis_multi_overview.item(row_no).text())
2217
2218            self._active_task = tasks.Task(
2219                target=main_presenter_async.run_distance_analysis,
2220                args=(
2221                    tmp_raw_analysis_run_names,
2222                    self._current_project,
2223                    self._application_settings,
2224                    self._view.ui.cb_pred_analysis_multi_images.isChecked(),
2225                ),
2226                post_func=self.post_analysis_process,
2227            )
2228            self._active_task.start()
2229
2230            if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2231                os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2232            self.block_box_analysis.exec_()
2233            self.display_view_page()
2234
2235        elif tmp_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
2236            self.block_box_prediction.destroy(True)
2237            basic_boxes.ok(
2238                "Prediction",
2239                "Prediction failed because there was an error writing the fasta file(s)!",
2240                QtWidgets.QMessageBox.Critical,
2241            )
2242            self.display_view_page()
2243            self._project_watcher.show_valid_options(self._view.ui)
2244            constants.PYSSA_LOGGER.error(
2245                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2246            )
2247            self._view.wait_spinner.stop()
2248        elif tmp_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
2249            self.block_box_prediction.destroy(True)
2250            basic_boxes.ok(
2251                "Prediction",
2252                "Prediction failed because the fasta file(s) could not be found!",
2253                QtWidgets.QMessageBox.Critical,
2254            )
2255            self.display_view_page()
2256            self._project_watcher.show_valid_options(self._view.ui)
2257            constants.PYSSA_LOGGER.error(
2258                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2259            )
2260            self._view.wait_spinner.stop()
2261        elif tmp_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
2262            self.block_box_prediction.destroy(True)
2263            basic_boxes.ok(
2264                "Prediction",
2265                "Prediction failed because a subprocess failed!",
2266                QtWidgets.QMessageBox.Critical,
2267            )
2268            self.display_view_page()
2269            self._project_watcher.show_valid_options(self._view.ui)
2270            constants.PYSSA_LOGGER.error(
2271                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2272            )
2273            self._view.wait_spinner.stop()
2274        elif tmp_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2275            self.block_box_prediction.destroy(True)
2276            basic_boxes.ok(
2277                "Prediction",
2278                "Prediction failed because of an unknown error!",
2279                QtWidgets.QMessageBox.Critical,
2280            )
2281            self.display_view_page()
2282            self._project_watcher.show_valid_options(self._view.ui)
2283            constants.PYSSA_LOGGER.error(
2284                f"Prediction ended with exit code {tmp_exit_code}: {tmp_exit_code_description}",
2285            )
2286            self._view.wait_spinner.stop()
2287
2288    def multi_pred_analysis_structure_analysis_next_2(self) -> None:
2289        """Shows the gui elements to select the chains in protein 1."""
2290        self._view.wait_spinner.start()
2291        tmp_proteins_to_predict: list[str] = []
2292        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
2293            tmp_proteins_to_predict.append(
2294                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text(),
2295            )
2296        self._active_task = tasks.Task(
2297            target=main_presenter_async.check_chains_for_subsequent_analysis,
2298            args=(
2299                self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2300                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
2301                self._current_project,
2302                tmp_proteins_to_predict,
2303            ),
2304            post_func=self.__await_multi_pred_analysis_structure_analysis_next_2,
2305        )
2306        self._active_task.start()
2307
2308    def __await_multi_pred_analysis_structure_analysis_next_2(self, result: tuple) -> None:
2309        # fixme: something is not quite right with the detection of the chains!
2310        _, tmp_analysis_name = result
2311        if tmp_analysis_name != "":
2312            gui_elements_to_show = [
2313                self._view.ui.btn_pred_analysis_multi_remove,
2314                self._view.ui.btn_pred_analysis_multi_add,
2315                self._view.ui.lbl_pred_analysis_multi_overview,
2316                self._view.ui.list_pred_analysis_multi_overview,
2317                self._view.ui.lbl_pred_analysis_multi_images,
2318                self._view.ui.cb_pred_analysis_multi_images,
2319                self._view.ui.btn_pred_analysis_multi_start,
2320                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
2321            ]
2322            gui_elements_to_hide = [
2323                self._view.ui.box_pred_analysis_multi_prot_struct_1,
2324                self._view.ui.box_pred_analysis_multi_prot_struct_2,
2325                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
2326                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
2327                self._view.ui.lbl_analysis_batch_vs_3,
2328                self._view.ui.lbl_pred_analysis_multi_ref_chains,
2329                self._view.ui.list_pred_analysis_multi_ref_chains,
2330                self._view.ui.lbl_pred_analysis_multi_model_chains,
2331                self._view.ui.list_pred_analysis_multi_model_chains,
2332                self._view.ui.btn_pred_analysis_multi_back_3,
2333                self._view.ui.btn_pred_analysis_multi_next_2,
2334                self._view.ui.btn_pred_analysis_multi_back_4,
2335                self._view.ui.btn_pred_analysis_multi_next_3,
2336                self._view.ui.btn_pred_analysis_multi_back_5,
2337                self._view.ui.btn_pred_analysis_multi_next_4,
2338            ]
2339            gui_utils.show_gui_elements(gui_elements_to_show)
2340            gui_utils.hide_gui_elements(gui_elements_to_hide)
2341            item = QtWidgets.QListWidgetItem(tmp_analysis_name)
2342            self._view.ui.list_pred_analysis_multi_overview.addItem(item)
2343            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
2344        else:
2345            gui_elements_to_show = [
2346                self._view.ui.lbl_pred_analysis_multi_overview,
2347                self._view.ui.list_pred_analysis_multi_overview,
2348                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
2349                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
2350                self._view.ui.lbl_analysis_batch_vs_3,
2351                self._view.ui.lbl_pred_analysis_multi_ref_chains,
2352                self._view.ui.list_pred_analysis_multi_ref_chains,
2353                self._view.ui.btn_pred_analysis_multi_back_4,
2354                self._view.ui.btn_pred_analysis_multi_next_3,
2355            ]
2356            gui_elements_to_hide = [
2357                self._view.ui.btn_pred_analysis_multi_remove,
2358                self._view.ui.btn_pred_analysis_multi_add,
2359                self._view.ui.box_pred_analysis_multi_prot_struct_1,
2360                self._view.ui.box_pred_analysis_multi_prot_struct_2,
2361                self._view.ui.btn_pred_analysis_multi_back_3,
2362                self._view.ui.btn_pred_analysis_multi_next_2,
2363                self._view.ui.lbl_pred_analysis_multi_model_chains,
2364                self._view.ui.list_pred_analysis_multi_model_chains,
2365                self._view.ui.btn_pred_analysis_multi_back_5,
2366                self._view.ui.btn_pred_analysis_multi_next_4,
2367                self._view.ui.lbl_pred_analysis_multi_images,
2368                self._view.ui.cb_pred_analysis_multi_images,
2369                self._view.ui.btn_pred_analysis_multi_start,
2370                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
2371            ]
2372            gui_utils.show_gui_elements(gui_elements_to_show)
2373            gui_utils.hide_gui_elements(gui_elements_to_hide)
2374            self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText(
2375                self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2376            )
2377            self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText(
2378                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
2379            )
2380            self._view.ui.list_pred_analysis_multi_ref_chains.clear()
2381            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(False)
2382            self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(True)
2383
2384            for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
2385                if (
2386                    self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text()
2387                    == self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText()
2388                ):
2389                    self._view.ui.list_pred_analysis_multi_ref_chains.addItem(
2390                        self._view.ui.table_pred_analysis_multi_prot_to_predict.item(i, 0).text(),
2391                    )
2392            if self._view.ui.list_pred_analysis_multi_ref_chains.count() == 0:
2393                tmp_protein = self._current_project.search_protein(
2394                    self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2395                )
2396                for tmp_chain in tmp_protein.chains:
2397                    if tmp_chain.chain_type == "protein_chain":
2398                        self._view.ui.list_pred_analysis_multi_ref_chains.addItem(tmp_chain.chain_letter)
2399            if self._view.ui.list_pred_analysis_multi_ref_chains.count() == 1:
2400                self._view.ui.lbl_pred_analysis_multi_ref_chains.setText(
2401                    f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()}.",
2402                )
2403            else:
2404                self._view.ui.lbl_pred_analysis_multi_ref_chains.setText(
2405                    f"Select chains in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()}.",
2406                )
2407        self._view.wait_spinner.stop()
2408
2409    # </editor-fold>
2410
2411    # <editor-fold desc="Structure Analysis functions">
2412    def post_analysis_process(self, an_exit_code: tuple[int, str]) -> None:
2413        """Post process after the analysis thread finished."""
2414        constants.PYSSA_LOGGER.debug("post_analysis_process() started ...")
2415        if an_exit_code[0] == exit_codes.ERROR_DISTANCE_ANALYSIS_FAILED[0]:
2416            self.block_box_analysis.destroy(True)
2417            basic_boxes.ok(
2418                "Distance analysis",
2419                "Distance analysis failed because there was an error during the analysis!",
2420                QtWidgets.QMessageBox.Critical,
2421            )
2422            constants.PYSSA_LOGGER.error(
2423                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2424            )
2425        elif an_exit_code[0] == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2426            self.block_box_analysis.destroy(True)
2427            basic_boxes.ok(
2428                "Distance analysis",
2429                "Distance analysis failed because of an unknown error!",
2430                QtWidgets.QMessageBox.Critical,
2431            )
2432            constants.PYSSA_LOGGER.error(
2433                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2434            )
2435        elif an_exit_code[0] == exit_codes.EXIT_CODE_ZERO[0]:
2436            self._current_project.serialize_project(self._current_project.get_project_xml_path())
2437            constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2438            self.block_box_analysis.destroy(True)
2439            basic_boxes.ok(
2440                "Structure analysis",
2441                "All structure analysis' are done. Go to results to check the new results.",
2442                QtWidgets.QMessageBox.Information,
2443            )
2444            constants.PYSSA_LOGGER.info("All structure analysis' are done.")
2445
2446        self._project_watcher.show_valid_options(self._view.ui)
2447        self.display_view_page()
2448        self._init_batch_analysis_page()
2449
2450    def start_process_batch(self) -> None:
2451        """Sets up the worker for the analysis task."""
2452        constants.PYSSA_LOGGER.info("Begin analysis process.")
2453
2454        tmp_raw_analysis_run_names: list = []
2455        for row_no in range(self._view.ui.list_analysis_batch_overview.count()):
2456            tmp_raw_analysis_run_names.append(self._view.ui.list_analysis_batch_overview.item(row_no).text())
2457        self._active_task = tasks.Task(
2458            target=main_presenter_async.run_distance_analysis,
2459            args=(
2460                tmp_raw_analysis_run_names,
2461                self._current_project,
2462                self._application_settings,
2463                self._view.ui.cb_analysis_images.isChecked(),
2464            ),
2465            post_func=self.post_analysis_process,
2466        )
2467        self._active_task.start()
2468
2469        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2470            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2471
2472        self.block_box_analysis.exec_()
2473        self.display_view_page()
2474
2475    def structure_analysis_next(self) -> None:
2476        """Shows the gui elements to select the chains in protein 1."""
2477        self._view.wait_spinner.start()
2478        self._active_task = tasks.Task(
2479            target=main_presenter_async.check_chains_for_analysis,
2480            args=(
2481                self._view.ui.box_analysis_batch_prot_struct_1.currentText(),
2482                self._view.ui.box_analysis_batch_prot_struct_2.currentText(),
2483                self._current_project,
2484            ),
2485            post_func=self.__await_structure_analysis_next,
2486        )
2487        self._active_task.start()
2488
2489    def __await_structure_analysis_next(self, result: tuple) -> None:
2490        _, tmp_is_only_one_chain, tmp_analysis_run_name, tmp_protein_1, tmp_protein_2 = result
2491
2492        if tmp_is_only_one_chain:
2493            gui_elements_to_show = [
2494                self._view.ui.btn_analysis_batch_remove,
2495                self._view.ui.btn_analysis_batch_add,
2496                self._view.ui.lbl_analysis_batch_overview,
2497                self._view.ui.list_analysis_batch_overview,
2498                self._view.ui.lbl_analysis_batch_images,
2499                self._view.ui.cb_analysis_batch_images,
2500                self._view.ui.btn_analysis_batch_start,
2501            ]
2502            gui_elements_to_hide = [
2503                self._view.ui.box_analysis_batch_prot_struct_1,
2504                self._view.ui.box_analysis_batch_prot_struct_2,
2505                self._view.ui.lbl_analysis_batch_prot_struct_1,
2506                self._view.ui.lbl_analysis_batch_prot_struct_2,
2507                self._view.ui.lbl_analysis_batch_vs,
2508                self._view.ui.lbl_analysis_batch_ref_chains,
2509                self._view.ui.list_analysis_batch_ref_chains,
2510                self._view.ui.lbl_analysis_batch_model_chains,
2511                self._view.ui.list_analysis_batch_model_chains,
2512                self._view.ui.btn_analysis_batch_back,
2513                self._view.ui.btn_analysis_batch_next,
2514                self._view.ui.btn_analysis_batch_back_2,
2515                self._view.ui.btn_analysis_batch_next_2,
2516                self._view.ui.btn_analysis_batch_back_3,
2517                self._view.ui.btn_analysis_batch_next_3,
2518            ]
2519            gui_utils.show_gui_elements(gui_elements_to_show)
2520            gui_utils.hide_gui_elements(gui_elements_to_hide)
2521            item = QtWidgets.QListWidgetItem(tmp_analysis_run_name)
2522            self._view.ui.list_analysis_batch_overview.addItem(item)
2523            self._view.ui.btn_analysis_batch_remove.setEnabled(False)
2524        else:
2525            gui_elements_to_show = [
2526                self._view.ui.lbl_analysis_batch_overview,
2527                self._view.ui.list_analysis_batch_overview,
2528                self._view.ui.lbl_analysis_batch_prot_struct_1,
2529                self._view.ui.lbl_analysis_batch_prot_struct_2,
2530                self._view.ui.lbl_analysis_batch_vs,
2531                self._view.ui.lbl_analysis_batch_ref_chains,
2532                self._view.ui.list_analysis_batch_ref_chains,
2533                self._view.ui.btn_analysis_batch_back_2,
2534                self._view.ui.btn_analysis_batch_next_2,
2535            ]
2536            gui_elements_to_hide = [
2537                self._view.ui.btn_analysis_batch_remove,
2538                self._view.ui.btn_analysis_batch_add,
2539                self._view.ui.box_analysis_batch_prot_struct_1,
2540                self._view.ui.box_analysis_batch_prot_struct_2,
2541                self._view.ui.btn_analysis_batch_back,
2542                self._view.ui.btn_analysis_batch_next,
2543                self._view.ui.lbl_analysis_batch_model_chains,
2544                self._view.ui.list_analysis_batch_model_chains,
2545                self._view.ui.btn_analysis_batch_back_3,
2546                self._view.ui.btn_analysis_batch_next_3,
2547                self._view.ui.lbl_analysis_batch_images,
2548                self._view.ui.cb_analysis_batch_images,
2549                self._view.ui.btn_analysis_batch_start,
2550            ]
2551            gui_utils.show_gui_elements(gui_elements_to_show)
2552            gui_utils.hide_gui_elements(gui_elements_to_hide)
2553            self._view.ui.lbl_analysis_batch_prot_struct_1.setText(
2554                self._view.ui.box_analysis_batch_prot_struct_1.currentText(),
2555            )
2556            self._view.ui.lbl_analysis_batch_prot_struct_2.setText(
2557                self._view.ui.box_analysis_batch_prot_struct_2.currentText(),
2558            )
2559            self._view.ui.list_analysis_batch_ref_chains.clear()
2560            self._view.ui.btn_analysis_batch_next_2.setEnabled(False)
2561            self._view.ui.list_analysis_batch_ref_chains.setEnabled(True)
2562
2563            for tmp_chain in tmp_protein_1.chains:
2564                if tmp_chain.chain_type == "protein_chain":
2565                    self._view.ui.list_analysis_batch_ref_chains.addItem(tmp_chain.chain_letter)
2566
2567            if self._view.ui.list_analysis_batch_ref_chains.count() == 1:
2568                self._view.ui.lbl_analysis_batch_ref_chains.setText(
2569                    f"Select chain in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_1.text()}.",
2570                )
2571            else:
2572                self._view.ui.lbl_analysis_batch_ref_chains.setText(
2573                    f"Select chains in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_1.text()}.",
2574                )
2575        self._view.wait_spinner.stop()
2576
2577    # </editor-fold>
2578
2579    # <editor-fold desc="Analysis Images">
2580    def post_image_creation_process(self) -> None:
2581        """Post method after the image creation task is finished."""
2582        self._current_project.serialize_project(self._current_project.get_project_xml_path())
2583        constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2584        self.block_box_images.destroy(True)
2585        basic_boxes.ok(
2586            "Analysis Images",
2587            "All images of all analysis' have been created. Go to results to check the new results.",
2588            QtWidgets.QMessageBox.Information,
2589        )
2590        constants.PYSSA_LOGGER.info("All images of all analysis' have been created.")
2591        self._init_analysis_image_page()
2592        self.display_view_page()
2593        self._project_watcher.show_valid_options(self._view.ui)
2594
2595    def start_automatic_image_creation(self) -> None:
2596        """Sets up the worker for the image creation process."""
2597        constants.PYSSA_LOGGER.info("Begin image creation process.")
2598        # self.worker_image_creation = workers.BatchImageWorkerPool(
2599        #    self._view.ui.list_analysis_images_struct_analysis, self._view.ui.list_analysis_images_creation_struct_analysis,
2600        #    self._view.status_bar, self._current_project)
2601        constants.PYSSA_LOGGER.info("Thread started for image creation process.")
2602        # self.threadpool.start(self.worker_image_creation)
2603
2604        # <editor-fold desc="Worker setup">
2605        # TODO: test code below
2606        # --Begin: worker setup
2607        self.tmp_thread = QtCore.QThread()
2608        self.tmp_worker = task_workers.BatchImageWorker(
2609            self._view.ui.list_analysis_images_struct_analysis,
2610            self._view.ui.list_analysis_images_creation_struct_analysis,
2611            self._view.status_bar,
2612            self._current_project,
2613        )
2614        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.display_view_page)
2615        self.tmp_worker.finished.connect(self.post_image_creation_process)
2616        self.tmp_thread.start()
2617        # --End: worker setup
2618
2619        # </editor-fold>
2620
2621        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2622            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2623
2624        self._view.ui.list_analysis_images_struct_analysis.setEnabled(False)
2625        self._view.ui.list_analysis_images_creation_struct_analysis.setEnabled(False)
2626
2627        # gui_elements_to_show = [
2628        #     self._view.ui.btn_analysis_abort,
2629        # ]
2630        # gui_elements_to_hide = [
2631        #     self._view.ui.btn_save_project,
2632        #     self._view.ui.btn_edit_page,
2633        #     self._view.ui.btn_view_page,
2634        #     self._view.ui.btn_use_page,
2635        #     self._view.ui.btn_export_project,
2636        #     self._view.ui.btn_close_project,
2637        #     self._view.ui.btn_batch_analysis_page,
2638        #     self._view.ui.btn_image_analysis_page,
2639        #     self._view.ui.btn_results_page,
2640        #     self._view.ui.lbl_handle_pymol_session,
2641        #     self._view.ui.btn_image_page,
2642        #     self._view.ui.btn_hotspots_page,
2643        # ]
2644        # gui_utils.manage_gui_visibility(gui_elements_to_show, gui_elements_to_hide)
2645
2646        self.block_box_images.exec_()
2647
2648    # </editor-fold>
2649
2650    # <editor-fold desc="Results page functions">
2651    def show_analysis_results_options(self) -> None:
2652        """Shows the combo box of protein pairs."""
2653        self.results_management.show_stage_x(0)
2654
2655    def show_results_interactions(self, gui_elements_to_show: list = None, gui_elements_to_hide: list = None) -> None:
2656        """Shows the gui elements of the results page.
2657
2658        Args:
2659            gui_elements_to_show: a list of gui elements which should get displayed.
2660            gui_elements_to_hide: a list of gui elements which should get hidden.
2661        """
2662        if gui_elements_to_hide is not None:
2663            self.results_management.show_gui_elements_stage_x(
2664                [0, 1],
2665                [],
2666                show_specific_elements=[
2667                    self._view.ui.lbl_results_analysis_options,
2668                    self._view.ui.cb_results_analysis_options,
2669                ],
2670                hide_specific_elements=gui_elements_to_hide,
2671            )
2672        else:
2673            self.results_management.show_gui_elements_stage_x(
2674                [0, 1],
2675                [],
2676                show_specific_elements=[
2677                    self._view.ui.lbl_results_analysis_options,
2678                    self._view.ui.cb_results_analysis_options,
2679                ],
2680            )
2681
2682    def load_results(self) -> None:
2683        """Sets up the worker for the result loading process."""
2684        self._view.wait_spinner.start()
2685        if self.is_distance_plot_open:
2686            self.distance_plot_dialog.close()
2687            self.is_distance_plot_open = False
2688        self.results_name = self._view.ui.cb_results_analysis_options.currentText()
2689        if self.results_name == "":
2690            self.show_analysis_results_options()
2691            self._view.wait_spinner.stop()
2692            return
2693        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
2694
2695        self._active_task = tasks.Task(
2696            target=main_presenter_async.load_results,
2697            args=(
2698                self._current_project,
2699                self.results_name,
2700            ),
2701            post_func=self.__await_load_results,
2702        )
2703        self._active_task.start()
2704
2705        self._view.ui.list_results_interest_regions.clear()
2706        self._view.status_bar.showMessage(f"Loading results of {self.results_name} ...")
2707
2708    def __await_load_results(self, result: tuple) -> None:
2709        _, images_type, self.current_session, tmp_rmsd, tmp_no_aligned_residues = result
2710
2711        if images_type == constants.IMAGES_ALL:
2712            gui_elements_to_show = [
2713                self._view.ui.lbl_results_analysis_options,
2714                self._view.ui.cb_results_analysis_options,
2715                self._view.ui.lbl_results_rmsd,
2716                self._view.ui.txt_results_rmsd,
2717                self._view.ui.lbl_color_rmsd,
2718                self._view.ui.btn_color_rmsd,
2719                self._view.ui.lbl_results_aligned_residues,
2720                self._view.ui.txt_results_aligned_residues,
2721                self._view.ui.lbl_results_distance_plot,
2722                self._view.ui.btn_view_distance_plot,
2723                self._view.ui.lbl_results_distance_histogram,
2724                self._view.ui.btn_view_distance_histogram,
2725                self._view.ui.lbl_results_distance_table,
2726                self._view.ui.btn_view_distance_table,
2727                self._view.ui.lbl_results_structure_alignment,
2728                self._view.ui.btn_view_struct_alignment,
2729                self._view.ui.lbl_results_interest_regions,
2730                self._view.ui.list_results_interest_regions,
2731                self._view.ui.btn_view_interesting_region,
2732            ]
2733            gui_utils.show_gui_elements(gui_elements_to_show)
2734            for tmp_filename in os.listdir(constants.CACHE_STRUCTURE_ALN_IMAGES_INTERESTING_REGIONS_DIR):
2735                self._view.ui.list_results_interest_regions.addItem(tmp_filename)
2736            self._view.ui.list_results_interest_regions.sortItems()
2737        elif images_type == constants.IMAGES_STRUCT_ALN_ONLY:
2738            gui_elements_to_show = [
2739                self._view.ui.lbl_results_analysis_options,
2740                self._view.ui.cb_results_analysis_options,
2741                self._view.ui.lbl_results_rmsd,
2742                self._view.ui.txt_results_rmsd,
2743                self._view.ui.lbl_color_rmsd,
2744                self._view.ui.btn_color_rmsd,
2745                self._view.ui.lbl_results_aligned_residues,
2746                self._view.ui.txt_results_aligned_residues,
2747                self._view.ui.lbl_results_distance_plot,
2748                self._view.ui.btn_view_distance_plot,
2749                self._view.ui.lbl_results_distance_histogram,
2750                self._view.ui.btn_view_distance_histogram,
2751                self._view.ui.lbl_results_distance_table,
2752                self._view.ui.btn_view_distance_table,
2753                self._view.ui.lbl_results_structure_alignment,
2754                self._view.ui.btn_view_struct_alignment,
2755            ]
2756            gui_elements_to_hide = [
2757                self._view.ui.lbl_results_interest_regions,
2758                self._view.ui.list_results_interest_regions,
2759                self._view.ui.btn_view_interesting_region,
2760            ]
2761            gui_utils.show_gui_elements(gui_elements_to_show)
2762            gui_utils.hide_gui_elements(gui_elements_to_hide)
2763            self._view.ui.list_results_interest_regions.sortItems()
2764        elif images_type == constants.IMAGES_NONE:
2765            gui_elements_to_show = [
2766                self._view.ui.lbl_results_analysis_options,
2767                self._view.ui.cb_results_analysis_options,
2768                self._view.ui.lbl_results_rmsd,
2769                self._view.ui.txt_results_rmsd,
2770                self._view.ui.lbl_color_rmsd,
2771                self._view.ui.btn_color_rmsd,
2772                self._view.ui.lbl_results_aligned_residues,
2773                self._view.ui.txt_results_aligned_residues,
2774                self._view.ui.lbl_results_distance_plot,
2775                self._view.ui.btn_view_distance_plot,
2776                self._view.ui.lbl_results_distance_histogram,
2777                self._view.ui.btn_view_distance_histogram,
2778                self._view.ui.lbl_results_distance_table,
2779                self._view.ui.btn_view_distance_table,
2780            ]
2781            gui_elements_to_hide = [
2782                self._view.ui.lbl_results_structure_alignment,
2783                self._view.ui.btn_view_struct_alignment,
2784                self._view.ui.lbl_results_interest_regions,
2785                self._view.ui.list_results_interest_regions,
2786                self._view.ui.btn_view_interesting_region,
2787            ]
2788            gui_utils.show_gui_elements(gui_elements_to_show)
2789            gui_utils.hide_gui_elements(gui_elements_to_hide)
2790        else:
2791            raise ValueError("Illegal argument.")
2792
2793        self._view.ui.txt_results_rmsd.setText(str(tmp_rmsd))
2794        self._view.ui.txt_results_aligned_residues.setText(str(tmp_no_aligned_residues))
2795        self._view.status_bar.showMessage(f"Current workspace: {str(self._workspace_path)}")
2796        self.main_window_state.results_page.results_name = self._view.ui.cb_results_analysis_options.currentText()
2797        self._view.wait_spinner.stop()
2798
2799    def color_protein_pair_by_rmsd(self) -> None:
2800        """Colors the residues in 5 colors depending on their distance to the reference."""
2801        self._view.wait_spinner.start()
2802        self._active_task = tasks.Task(
2803            target=main_presenter_async.color_protein_pair_by_rmsd_value,
2804            args=(
2805                self._current_project,
2806                self.results_name,
2807            ),
2808            post_func=self.__await_color_protein_pair_by_rmsd,
2809        )
2810        self._active_task.start()
2811        self._view.status_bar.showMessage("Coloring protein pair by RMSD value ...")
2812        # hide unnecessary representations
2813        # fixme: it might be a problem to hide any representation at this point
2814        # cmd.hide("cartoon", tmp_protein_pair.protein_1.get_molecule_object())
2815        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")
2816        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")
2817
2818    def __await_color_protein_pair_by_rmsd(self, result: tuple) -> None:
2819        self._view.wait_spinner.stop()
2820
2821    # </editor-fold>
2822
2823    # <editor-fold desc="Display page functions">
2824    def display_structure_alignment(self) -> None:
2825        """Opens a window which displays the image of the structure alignment."""
2826        png_dialog = QtWidgets.QDialog(self._view)
2827        label = QtWidgets.QLabel(self._view)
2828        pathlib.Path(
2829            f"{self._workspace_path}/{self._view.ui.lbl_current_project_name.text()}/results/{self.results_name}",
2830        )
2831        self._view.ui.cb_results_analysis_options.currentText()
2832        pixmap = QtGui.QPixmap(
2833            f"{constants.CACHE_STRUCTURE_ALN_IMAGES_DIR}/structure_aln_{self._view.ui.cb_results_analysis_options.currentText()}",
2834        )
2835        # TO-DO: Create setting for min. image size
2836        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2837        label.setPixmap(pixmap)
2838        label.setScaledContents(True)
2839        png_dialog_layout = QtWidgets.QHBoxLayout()
2840        png_dialog_layout.addWidget(label)
2841        png_dialog.setLayout(png_dialog_layout)
2842        png_dialog.setWindowTitle("Image of: structure alignment")
2843        png_dialog.show()
2844
2845    def display_distance_plot(self) -> None:
2846        """Opens a window which displays the distance plot."""
2847        protein_pair_of_analysis = self._current_project.search_protein_pair(
2848            self._view.ui.cb_results_analysis_options.currentText(),
2849        )
2850
2851        tmp_dialog = plot_view.PlotView(protein_pair_of_analysis, self._current_project, self._view.ui.cb_results_analysis_options.currentText())
2852        tmp_dialog.exec_()
2853
2854        # self.distance_plot_dialog = dialog_distance_plot.DialogDistancePlot(protein_pair_of_analysis, self._current_project,
2855        #                                                                     self._view.ui.cb_results_analysis_options.currentText())
2856        # self.distance_plot_dialog.setWindowModality(Qt.WindowModal)
2857        # self.is_distance_plot_open = True
2858        # self.distance_plot_dialog.exec_()
2859
2860    def display_distance_histogram(self) -> None:
2861        """Opens a window which displays the distance histogram."""
2862        if self.is_distance_plot_open:
2863            self.distance_plot_dialog.close()
2864            self.is_distance_plot_open = False
2865        protein_pair_of_analysis = self._current_project.search_protein_pair(
2866            self._view.ui.cb_results_analysis_options.currentText(),
2867        )
2868        dialog = dialog_distance_histogram.DialogDistanceHistogram(protein_pair_of_analysis)
2869        dialog.exec_()
2870
2871    def display_interesting_region(self) -> None:
2872        """Displays an image of an interesting region."""
2873        if self.is_distance_plot_open:
2874            self.distance_plot_dialog.close()
2875            self.is_distance_plot_open = False
2876        png_dialog = QtWidgets.QDialog(self._view)
2877        label = QtWidgets.QLabel(self._view)
2878        file_name = self._view.ui.list_results_interest_regions.currentItem().text()
2879        pixmap = QtGui.QPixmap(f"{constants.CACHE_STRUCTURE_ALN_IMAGES_INTERESTING_REGIONS_DIR}/{file_name}")
2880        # TODO: Create setting for min. image size
2881        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2882        label.setPixmap(pixmap)
2883        label.setScaledContents(True)
2884        png_dialog_layout = QtWidgets.QHBoxLayout()
2885        png_dialog_layout.addWidget(label)
2886        png_dialog.setLayout(png_dialog_layout)
2887        png_dialog.setWindowTitle(f"Image of: {file_name}")
2888        png_dialog.show()
2889
2890    def display_distance_table(self) -> None:
2891        """Displays the distances in a table."""
2892        if self.is_distance_plot_open:
2893            self.distance_plot_dialog.close()
2894            self.is_distance_plot_open = False
2895        csv_model = QtGui.QStandardItemModel()
2896        csv_model.setColumnCount(7)
2897        labels = [
2898            "Residue pair no.",
2899            "Protein 1 Chain",
2900            "Protein 1 Position",
2901            "Protein 1 Residue",
2902            "Protein 2 Chain",
2903            "Protein 2 Position",
2904            "Protein 2 Residue",
2905            "Distance in Ã…",
2906        ]
2907        csv_model.setHorizontalHeaderLabels(labels)
2908        table_dialog = QtWidgets.QDialog(self._view)
2909        table_view = QtWidgets.QTableView()
2910        table_view.setModel(csv_model)
2911
2912        tmp_protein_pair = self._current_project.search_protein_pair(
2913            self._view.ui.cb_results_analysis_options.currentText(),
2914        )
2915        csv_filepath = pathlib.Path(f"{constants.CACHE_CSV_DIR}/{tmp_protein_pair.name}.csv")
2916        if not os.path.exists(constants.CACHE_CSV_DIR):
2917            os.mkdir(constants.CACHE_CSV_DIR)
2918        tmp_protein_pair = self._current_project.search_protein_pair(self.results_name)
2919
2920        distance_data = tmp_protein_pair.distance_analysis.analysis_results.distance_data
2921        distance_data_array = np.array(
2922            [
2923                distance_data[pyssa_keys.ARRAY_DISTANCE_INDEX],
2924                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_CHAIN],
2925                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_POSITION],
2926                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_RESI],
2927                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_CHAIN],
2928                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_POSITION],
2929                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_RESI],
2930                distance_data[pyssa_keys.ARRAY_DISTANCE_DISTANCES],
2931            ],
2932        )
2933        distance_data_array_transpose = distance_data_array.transpose()
2934        with open(csv_filepath, mode="w", newline="") as file:
2935            writer = csv.writer(file, delimiter=",")
2936            writer.writerows(distance_data_array_transpose)
2937
2938        file.close()
2939
2940        with open(csv_filepath, "r", encoding="utf-8") as csv_file:
2941            i = 0
2942            for line in csv_file:
2943                tmp_list = line.split(",")
2944                # tmp_list.pop(0)
2945                standard_item_list = []
2946                pair_no_item = QtGui.QStandardItem()
2947                pair_no_item.setData(int(tmp_list[0]), role=QtCore.Qt.DisplayRole)
2948                ref_chain_item = QtGui.QStandardItem()
2949                ref_chain_item.setData(str(tmp_list[1]), role=QtCore.Qt.DisplayRole)
2950                ref_pos_item = QtGui.QStandardItem()
2951                ref_pos_item.setData(int(tmp_list[2]), role=QtCore.Qt.DisplayRole)
2952                ref_resi_item = QtGui.QStandardItem()
2953                ref_resi_item.setData(str(tmp_list[3]), role=QtCore.Qt.DisplayRole)
2954                model_chain_item = QtGui.QStandardItem()
2955                model_chain_item.setData(str(tmp_list[4]), role=QtCore.Qt.DisplayRole)
2956                model_pos_item = QtGui.QStandardItem()
2957                model_pos_item.setData(int(tmp_list[5]), role=QtCore.Qt.DisplayRole)
2958                model_resi_item = QtGui.QStandardItem()
2959                model_resi_item.setData(str(tmp_list[6]), role=QtCore.Qt.DisplayRole)
2960                distance_item = QtGui.QStandardItem()
2961                distance_item.setData(float(tmp_list[7]), role=QtCore.Qt.DisplayRole)
2962                standard_item_list.append(pair_no_item)
2963                standard_item_list.append(ref_chain_item)
2964                standard_item_list.append(ref_pos_item)
2965                standard_item_list.append(ref_resi_item)
2966                standard_item_list.append(model_chain_item)
2967                standard_item_list.append(model_pos_item)
2968                standard_item_list.append(model_resi_item)
2969                standard_item_list.append(distance_item)
2970                csv_model.insertRow(i, standard_item_list)
2971            i += 1
2972        csv_file.close()
2973        csv_model.removeRow(0)
2974        table_view.setAlternatingRowColors(True)
2975        table_view.resizeColumnsToContents()
2976        table_view.verticalHeader().setVisible(False)
2977        table_view.setSortingEnabled(True)
2978        table_view.sortByColumn(0, QtCore.Qt.AscendingOrder)
2979        table_dialog_layout = QtWidgets.QHBoxLayout()
2980        table_dialog_layout.addWidget(table_view)
2981        table_dialog.setLayout(table_dialog_layout)
2982        # styles
2983        stylesheet = """
2984        QDialog {background-color: #F6F4F8;}
2985        QTableView {background-color: white;}
2986        """
2987        table_dialog.setStyleSheet(stylesheet)
2988        table_dialog.setWindowFlag(QtCore.Qt.WindowMaximizeButtonHint, True)
2989        table_dialog.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, True)
2990        table_dialog.setModal(True)
2991        table_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # disables editing of cells
2992        table_dialog.setWindowTitle("Distances of Structure Alignment")
2993        table_dialog.show()
2994
2995    # </editor-fold>
2996
2997    # <editor-fold desc="Manage page functions">
2998    def choose_manage_open_protein(self) -> None:
2999        """Shows the different configuration gui elements."""
3000        if self._view.ui.box_manage_choose_protein.currentText() != "":
3001            gui_elements_to_show = [
3002                self._view.ui.lbl_manage_choose_color,
3003                self._view.ui.box_manage_choose_color,
3004                self._view.ui.lbl_manage_choose_representation,
3005                self._view.ui.box_manage_choose_representation,
3006                self._view.ui.lbl_manage_choose_bg_color,
3007                self._view.ui.box_manage_choose_bg_color,
3008            ]
3009            gui_utils.show_gui_elements(gui_elements_to_show)
3010            tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3011            if (
3012                cmd.select(
3013                    name="disulfides",
3014                    selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3015                )
3016                > 0
3017            ):
3018                gui_elements_to_show = [
3019                    self._view.ui.lbl_disulfid_bond_1,
3020                    self._view.ui.lbl_disulfid_bond_2,
3021                    self._view.ui.btn_disulfid_bond_show,
3022                    self._view.ui.btn_disulfid_bond_hide,
3023                ]
3024                gui_utils.show_gui_elements(gui_elements_to_show)
3025        else:
3026            gui_elements_to_hide = [
3027                self._view.ui.lbl_manage_choose_color,
3028                self._view.ui.box_manage_choose_color,
3029                self._view.ui.lbl_manage_choose_representation,
3030                self._view.ui.box_manage_choose_representation,
3031                self._view.ui.lbl_manage_choose_bg_color,
3032                self._view.ui.box_manage_choose_bg_color,
3033                self._view.ui.lbl_disulfid_bond_1,
3034                self._view.ui.lbl_disulfid_bond_2,
3035                self._view.ui.btn_disulfid_bond_show,
3036                self._view.ui.btn_disulfid_bond_hide,
3037            ]
3038            gui_utils.hide_gui_elements(gui_elements_to_hide)
3039
3040    def choose_manage_color_selected_protein(self) -> None:
3041        """Sets the protein color."""
3042        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3043        tmp_protein = self._current_project.search_protein(tmp_input)
3044        tmp_protein.color_protein_in_pymol(
3045            self._view.ui.box_manage_choose_color.currentText(),
3046            f"/{tmp_protein.get_molecule_object()}",
3047        )
3048
3049    def choose_manage_representation(self) -> None:
3050        """Sets the representation."""
3051        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3052        tmp_protein = self._current_project.search_protein(tmp_input)
3053        tmp_selection = f"/{tmp_protein.get_molecule_object()}"
3054        if self._view.ui.box_manage_choose_representation.currentIndex() == 0:
3055            print("Please select a representation.")
3056            self._view.status_bar.showMessage("Please select a representation.")
3057        elif self._view.ui.box_manage_choose_representation.currentIndex() == 1:
3058            cmd.show("cartoon", tmp_selection)
3059            cmd.hide("ribbon", tmp_selection)
3060        elif self._view.ui.box_manage_choose_representation.currentIndex() == 2:
3061            cmd.show("ribbon", tmp_selection)
3062            cmd.hide("cartoon", tmp_selection)
3063        else:
3064            print("Missing implementation!")
3065
3066    def choose_manage_bg_color(self) -> None:
3067        """Sets the background color."""
3068        if self._view.ui.box_manage_choose_bg_color.currentIndex() == 0:
3069            print("Please select a background color.")
3070            self._view.status_bar.showMessage("Please select a background color.")
3071        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 1:
3072            cmd.bg_color("black")
3073        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 2:
3074            cmd.bg_color("white")
3075        else:
3076            print("Missing implementation!")
3077
3078    def show_disulfid_bonds_as_sticks(self) -> None:
3079        """Shows all disulfid bonds within the pymol session."""
3080        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3081        cmd.select(
3082            name="disulfides",
3083            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3084        )
3085        cmd.color(color="atomic", selection="disulfides and not elem C")
3086        cmd.set("valence", 0)  # this needs to be better implemented
3087        cmd.show("sticks", "disulfides")
3088        cmd.hide("sticks", "elem H")
3089
3090    def hide_disulfid_bonds_as_sticks(self) -> None:
3091        """Hides all disulfid bonds within the pymol session."""
3092        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3093        cmd.select(
3094            name="disulfides",
3095            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3096        )
3097        cmd.hide("sticks", "disulfides")
3098
3099    # </editor-fold>
3100
3101    # <editor-fold desc="Image page functions">
3102    def show_representation(self) -> None:
3103        """Sets the representation."""
3104        if self._view.ui.box_representation.currentIndex() == 0:
3105            self.main_window_state.image_page.representation = ""
3106            self._view.status_bar.showMessage("Please select a representation.")
3107        elif self._view.ui.box_representation.currentIndex() == 1:
3108            cmd.show("cartoon", "all")
3109            cmd.hide("ribbon", "all")
3110            self.main_window_state.image_page.representation = "cartoon"
3111        elif self._view.ui.box_representation.currentIndex() == 2:
3112            cmd.show("ribbon", "all")
3113            cmd.hide("cartoon", "all")
3114            self.main_window_state.image_page.representation = "ribbon"
3115        else:
3116            print("Missing implementation!")
3117
3118    def choose_bg_color(self) -> None:
3119        """Sets the background color."""
3120        if self._view.ui.box_bg_color.currentIndex() == 0:
3121            self.main_window_state.image_page.background_color = ""
3122            self._view.status_bar.showMessage("Please select a background color.")
3123        elif self._view.ui.box_bg_color.currentIndex() == 1:
3124            cmd.bg_color("black")
3125            self.main_window_state.image_page.background_color = "black"
3126        elif self._view.ui.box_bg_color.currentIndex() == 2:
3127            cmd.bg_color("white")
3128            self.main_window_state.image_page.background_color = "white"
3129        else:
3130            print("Missing implementation!")
3131
3132    def choose_renderer(self) -> None:
3133        """Sets the renderer."""
3134        if self._view.ui.box_renderer.currentIndex() == 0:
3135            self._view.status_bar.showMessage("Please select a renderer.")
3136            self._view.ui.cb_ray_tracing.hide()
3137            self._view.ui.label_26.hide()
3138        elif self._view.ui.box_renderer.currentIndex() == 1:
3139            self.renderer = "-1"
3140            self._view.ui.cb_ray_tracing.show()
3141            self._view.ui.label_26.show()
3142        elif self._view.ui.box_renderer.currentIndex() == 2:
3143            self.renderer = "0"
3144            self._view.ui.cb_ray_tracing.show()
3145            self._view.ui.label_26.show()
3146        else:
3147            print("Missing implementation!")
3148        self.main_window_state.image_page.renderer = self._view.ui.box_renderer.currentIndex()
3149
3150    def choose_ray_trace_mode(self) -> None:
3151        """Sets the ray-trace mode."""
3152        if self._view.ui.box_ray_trace_mode.currentIndex() == 0:
3153            self._view.status_bar.showMessage("Please select a Ray-Trace-Mode.")
3154        elif self._view.ui.box_ray_trace_mode.currentIndex() == 1:
3155            cmd.set("ray_trace_mode", 0)
3156        elif self._view.ui.box_ray_trace_mode.currentIndex() == 2:
3157            cmd.set("ray_trace_mode", 1)
3158        elif self._view.ui.box_ray_trace_mode.currentIndex() == 3:
3159            cmd.set("ray_trace_mode", 2)
3160        elif self._view.ui.box_ray_trace_mode.currentIndex() == 4:
3161            cmd.set("ray_trace_mode", 3)
3162        else:
3163            print("Missing implementation!")
3164        self.main_window_state.image_page.ray_trace_mode = self._view.ui.box_ray_trace_mode.currentIndex()
3165
3166    def choose_ray_texture(self) -> None:
3167        """Sets the ray texture."""
3168        if self._view.ui.box_ray_texture.currentIndex() == 0:
3169            print("Please select a Ray Texture.")
3170            self._view.status_bar.showMessage("Please select a Ray Texture.")
3171        elif self._view.ui.box_ray_texture.currentIndex() == 1:
3172            cmd.set("ray_texture", 0)
3173        elif self._view.ui.box_ray_texture.currentIndex() == 2:
3174            cmd.set("ray_texture", 1)
3175        elif self._view.ui.box_ray_texture.currentIndex() == 3:
3176            cmd.set("ray_texture", 2)
3177        elif self._view.ui.box_ray_texture.currentIndex() == 4:
3178            cmd.set("ray_texture", 3)
3179        elif self._view.ui.box_ray_texture.currentIndex() == 5:
3180            cmd.set("ray_texture", 4)
3181        elif self._view.ui.box_ray_texture.currentIndex() == 6:
3182            cmd.set("ray_texture", 5)
3183        else:
3184            print("Missing implementation!")
3185        self.main_window_state.image_page.ray_texture = self._view.ui.box_ray_texture.currentIndex()
3186
3187    def decide_ray_tracing(self) -> None:
3188        """Sets the ray-tracing options."""
3189        print(self._view.ui.cb_ray_tracing.isChecked())
3190        if self._view.ui.cb_ray_tracing.isChecked():
3191            self._view.ui.cb_transparent_bg.hide()
3192            self._view.ui.label_23.hide()
3193            self._view.ui.box_renderer.setEnabled(False)
3194            self._view.ui.label_10.show()
3195            self._view.ui.box_ray_trace_mode.show()
3196            self._view.ui.label_14.show()
3197            self._view.ui.box_ray_texture.show()
3198            cmd.set("ray_opaque_background", "off")
3199        else:
3200            self._view.ui.cb_transparent_bg.show()
3201            self._view.ui.label_23.show()
3202            self._view.ui.box_renderer.setEnabled(True)
3203            self._view.ui.label_10.hide()
3204            self._view.ui.box_ray_trace_mode.hide()
3205            self._view.ui.label_14.hide()
3206            self._view.ui.box_ray_texture.hide()
3207        self.main_window_state.image_page.ray_tracing = self._view.ui.cb_ray_tracing.isChecked()
3208
3209    def decide_transparent_bg(self) -> None:
3210        """Sets the transparent background."""
3211        if self._view.ui.cb_transparent_bg.isChecked():
3212            cmd.set("opaque_background", "off")
3213        else:
3214            cmd.set("opaque_background", "on")
3215        self.main_window_state.image_page.transparent_background = self._view.ui.cb_transparent_bg.isChecked()
3216
3217    @staticmethod
3218    def update_scene() -> None:
3219        """Updates the current selected PyMOL scene."""
3220        cmd.scene(key="auto", action="update")
3221
3222    def save_scene(self) -> None:
3223        """Saves the current view as a new PyMOL scene."""
3224        # returns tuple with (name, bool)
3225        scene_name = QtWidgets.QInputDialog.getText(self._view, "Save Scene", "Enter scene name:")
3226        if scene_name[1]:
3227            cmd.scene(key=scene_name[0], action="append")
3228
3229    def post_preview_image(self) -> None:
3230        """Hides the block box of the preview process."""
3231        self.block_box_uni.hide()
3232        self.block_box_uni.destroy(True)
3233        self._view.status_bar.showMessage("Finished preview of ray-traced image.")
3234        QtWidgets.QApplication.restoreOverrideCursor()
3235
3236    def preview_image(self) -> None:
3237        """Previews the image."""
3238        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3239        if self._view.ui.cb_ray_tracing.isChecked():
3240            self._view.status_bar.showMessage("Preview ray-traced image ...")
3241            # <editor-fold desc="Worker setup">
3242            # --Begin: worker setup
3243            self.tmp_thread = QtCore.QThread()
3244            self.tmp_worker = task_workers.PreviewRayImageWorker(self.renderer)
3245            self.tmp_thread = task_workers.setup_worker_for_work(
3246                self.tmp_thread,
3247                self.tmp_worker,
3248                self.display_view_page,
3249            )
3250            self.tmp_worker.finished.connect(self.post_preview_image)
3251            self.tmp_thread.start()
3252            # --End: worker setup
3253
3254            # </editor-fold>
3255            gui_utils.setup_standard_block_box(
3256                self.block_box_uni,
3257                "Preview ray-trace image",
3258                "Creating preview for the ray-traced image ...",
3259            )
3260            self.block_box_uni.exec_()
3261        else:
3262            self._view.status_bar.showMessage("Preview draw image ...")
3263            cmd.draw(2400, 2400)
3264            self._view.status_bar.showMessage("Finished preview of drawn image.")
3265            QtWidgets.QApplication.restoreOverrideCursor()
3266
3267    def post_save_image(self) -> None:
3268        """Displays a message box which informs that the process has finished."""
3269        self.block_box_uni.hide()
3270        self.block_box_uni.destroy(True)
3271        self._view.status_bar.showMessage("Finished image creation.")
3272        QtWidgets.QApplication.restoreOverrideCursor()
3273        basic_boxes.ok("Finished image creation", "The image has been created.", QtWidgets.QMessageBox.Information)
3274
3275    def save_image(self) -> None:
3276        """Saves the image as a png file."""
3277        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3278        if self._view.ui.cb_ray_tracing.isChecked():
3279            save_dialog = QtWidgets.QFileDialog()
3280            try:
3281                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3282                if full_file_name == ("", ""):
3283                    tools.quick_log_and_display(
3284                        "info",
3285                        "No file has been selected.",
3286                        self._view.status_bar,
3287                        "No file has been selected.",
3288                    )
3289                    return
3290                self._view.status_bar.showMessage("Creating ray-traced image ...")
3291
3292                # <editor-fold desc="Worker setup">
3293                # --Begin: worker setup
3294                self.tmp_thread = QtCore.QThread()
3295                self.tmp_worker = task_workers.SaveRayImageWorker(self.renderer, full_file_name[0])
3296                self.tmp_thread = task_workers.setup_worker_for_work(
3297                    self.tmp_thread,
3298                    self.tmp_worker,
3299                    self.display_view_page,
3300                )
3301                self.tmp_worker.finished.connect(self.post_save_image)
3302                self.tmp_thread.start()
3303                # --End: worker setup
3304
3305                # </editor-fold>
3306                gui_utils.setup_standard_block_box(
3307                    self.block_box_uni,
3308                    "Save ray-trace image",
3309                    "Creating the ray-traced image ...",
3310                )
3311                self.block_box_uni.exec_()
3312
3313                # cmd.ray(2400, 2400, renderer=int(self.renderer))
3314                # cmd.png(full_file_name[0], dpi=300)
3315
3316            except FileExistsError:
3317                tools.quick_log_and_display(
3318                    "error",
3319                    "File exists already.",
3320                    self._view.status_bar,
3321                    "File exists already.",
3322                )
3323            except pymol.CmdException:
3324                tools.quick_log_and_display(
3325                    "error",
3326                    "Unexpected Error from PyMOL while saving the " "an image",
3327                    self._view.status_bar,
3328                    "Unexpected Error from PyMOL",
3329                )
3330        else:
3331            save_dialog = QtWidgets.QFileDialog()
3332            try:
3333                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3334                if full_file_name == ("", ""):
3335                    tools.quick_log_and_display(
3336                        "info",
3337                        "No file has been selected.",
3338                        self._view.status_bar,
3339                        "No file has been selected.",
3340                    )
3341                    return
3342                self._view.status_bar.showMessage("Creating draw image ...")
3343                cmd.draw(2400, 2400)
3344                cmd.png(full_file_name[0], dpi=300)
3345                self._view.status_bar.showMessage("Finished image creation.")
3346                basic_boxes.ok(
3347                    "Finished image creation",
3348                    "The image has been created.",
3349                    QtWidgets.QMessageBox.Information,
3350                )
3351            except FileExistsError:
3352                tools.quick_log_and_display(
3353                    "error",
3354                    "File exists already.",
3355                    self._view.status_bar,
3356                    "File exists already.",
3357                )
3358            except pymol.CmdException:
3359                tools.quick_log_and_display(
3360                    "error",
3361                    "Unexpected Error from PyMOL while saving the " "an image",
3362                    self._view.status_bar,
3363                    "Unexpected Error from PyMOL",
3364                )
3365            finally:
3366                QtWidgets.QApplication.restoreOverrideCursor()
3367
3368    # </editor-fold>
3369
3370    # <editor-fold desc="Hotspots page functions">
3371    def open_protein_for_hotspots(self) -> None:
3372        """Loads the selected protein's pymol session."""
3373        self._view.wait_spinner.start()
3374        try:
3375            tmp_name = self._view.ui.list_hotspots_choose_protein.currentItem().text()
3376        except AttributeError:
3377            self._view.wait_spinner.stop()
3378            return
3379        if self._view.ui.list_hotspots_choose_protein.currentItem().text() != "":
3380            tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
3381            self._active_task = tasks.Task(
3382                target=main_presenter_async.open_protein_for_hotspots,
3383                args=(
3384                    tmp_name,
3385                    self._current_project,
3386                    self.current_session,
3387                ),
3388                post_func=self.__await_open_protein_for_hotspots,
3389            )
3390            self._active_task.start()
3391            self.update_status("Loading PyMOL session ...")
3392        else:
3393            self._view.wait_spinner.stop()
3394            self.update_status(self._workspace_status)
3395
3396    def __await_open_protein_for_hotspots(self, result: tuple) -> None:
3397        _, is_protein, is_protein_pair, self.current_session = result
3398        if is_protein and not is_protein_pair:
3399            gui_elements_to_show = [
3400                self._view.ui.lbl_hotspots_resi_show,
3401                self._view.ui.btn_hotspots_resi_show,
3402                self._view.ui.lbl_hotspots_resi_hide,
3403                self._view.ui.btn_hotspots_resi_hide,
3404                self._view.ui.lbl_hotspots_resi_zoom,
3405                self._view.ui.btn_hotspots_resi_zoom,
3406                self._view.ui.btn_manage_session,
3407            ]
3408            gui_utils.show_gui_elements(gui_elements_to_show)
3409        elif is_protein_pair and not is_protein:
3410            gui_elements_to_show = [
3411                self._view.ui.lbl_hotspots_resi_show,
3412                self._view.ui.btn_hotspots_resi_show,
3413                self._view.ui.lbl_hotspots_resi_hide,
3414                self._view.ui.btn_hotspots_resi_hide,
3415                self._view.ui.lbl_hotspots_resi_zoom,
3416                self._view.ui.btn_hotspots_resi_zoom,
3417                self._view.ui.btn_manage_session,
3418            ]
3419            gui_utils.show_gui_elements(gui_elements_to_show)
3420        else:
3421            pass
3422        self._view.wait_spinner.stop()
3423        self.update_status(self._workspace_status)
3424
3425    @staticmethod
3426    def hide_resi_sticks() -> None:
3427        """Hides the balls and sticks representation of the pymol selection."""
3428        session_util.check_if_sele_is_empty()
3429        cmd.hide(representation="sticks", selection="sele")
3430
3431    @staticmethod
3432    def show_resi_sticks() -> None:
3433        """Shows the pymol selection as sticks."""
3434        session_util.check_if_sele_is_empty()
3435        cmd.show(representation="sticks", selection="sele and not hydrogens")
3436        cmd.select(name="sele", selection="sele and not hydrogens")
3437        cmd.color(color="atomic", selection="sele and not elem C")
3438        cmd.set("valence", 0)  # this needs to be better implemented
3439
3440    @staticmethod
3441    def zoom_resi_position() -> None:
3442        """Zooms to the pymol selection."""
3443        session_util.check_if_sele_is_empty()
3444        cmd.zoom(selection="sele", buffer=8.0, state=0, complete=0)
3445
3446    # </editor-fold>
3447
3448    # </editor-fold>
3449
3450    # <editor-fold desc="GUI related methods">
3451
3452    # <editor-fold desc="GUI page management functions">
3453    def _create_batch_analysis_management(self) -> None:
3454        """Creates a list of gui stages."""
3455        # gui element management
3456        tmp_stages = [
3457            # add a prot analysis: stage 0
3458            stage.Stage(
3459                {
3460                    "label_batch_analysis_overview": self._view.ui.lbl_analysis_batch_overview,
3461                    "box_protein_structure_1": self._view.ui.list_analysis_batch_overview,
3462                },
3463                {
3464                    "add_button": self._view.ui.btn_analysis_batch_add,
3465                    "remove_button": self._view.ui.btn_analysis_batch_remove,
3466                },
3467            ),
3468            # choose protein structures: stage 1
3469            stage.Stage(
3470                {
3471                    "label_protein_structure_1": self._view.ui.lbl_analysis_batch_prot_struct_1,
3472                    "box_protein_structure_1": self._view.ui.box_analysis_batch_prot_struct_1,
3473                    "label_vs": self._view.ui.lbl_analysis_batch_vs,
3474                    "label_protein_structure_2": self._view.ui.lbl_analysis_batch_prot_struct_2,
3475                    "box_protein_structure_2": self._view.ui.box_analysis_batch_prot_struct_2,
3476                },
3477                {
3478                    "next_button": self._view.ui.btn_analysis_batch_next,
3479                    "back_button": self._view.ui.btn_analysis_batch_back,
3480                },
3481            ),
3482            # choose chains from prot structure 1: stage 2
3483            stage.Stage(
3484                {
3485                    "label_protein_structure_1_chains": self._view.ui.lbl_analysis_batch_ref_chains,
3486                    "list_protein_structure_1_chains": self._view.ui.list_analysis_batch_ref_chains,
3487                },
3488                {
3489                    "back_button": self._view.ui.btn_analysis_batch_back_2,
3490                    "next_button": self._view.ui.btn_analysis_batch_next_2,
3491                },
3492            ),
3493            # choose chains from prot structure 2: stage 3
3494            stage.Stage(
3495                {
3496                    "label_protein_structure_2_chains": self._view.ui.lbl_analysis_batch_model_chains,
3497                    "list_protein_structure_2_chains": self._view.ui.list_analysis_batch_model_chains,
3498                },
3499                {
3500                    "back_button": self._view.ui.btn_analysis_batch_back_3,
3501                    "next_button": self._view.ui.btn_analysis_batch_next_3,
3502                },
3503            ),
3504            # start batch run: stage 4
3505            stage.Stage(
3506                {
3507                    "label_images": self._view.ui.lbl_analysis_batch_images,
3508                    "checkbox_images": self._view.ui.cb_analysis_batch_images,
3509                },
3510                {
3511                    "start_button": self._view.ui.btn_analysis_batch_start,
3512                },
3513            ),
3514        ]
3515        self.batch_analysis_management = gui_page_management.GuiPageManagement(tmp_stages)
3516
3517    def _create_results_management(self) -> None:
3518        """Creates a list of gui stages."""
3519        # gui element management
3520        tmp_stages = [
3521            # choose protein structures: stage 0
3522            stage.Stage(
3523                {
3524                    "label_analysis_options": self._view.ui.lbl_results_analysis_options,
3525                    "box_results_analysis_options": self._view.ui.cb_results_analysis_options,
3526                },
3527                {
3528                    "": None,
3529                },
3530            ),
3531            # choose chains from prot structure 1: stage 1
3532            stage.Stage(
3533                {
3534                    "label_results_rmsd": self._view.ui.lbl_results_rmsd,
3535                    "text_results_rmsd": self._view.ui.txt_results_rmsd,
3536                    "label_color_rmsd": self._view.ui.lbl_color_rmsd,
3537                    "button_color_rmsd": self._view.ui.btn_color_rmsd,
3538                    "label_results_aligned_residues": self._view.ui.lbl_results_aligned_residues,
3539                    "text_results_aligned_residues": self._view.ui.txt_results_aligned_residues,
3540                    "label_results_distance_plot": self._view.ui.lbl_results_distance_plot,
3541                    "button_view_distance_plot": self._view.ui.btn_view_distance_plot,
3542                    "label_results_distance_histogram": self._view.ui.lbl_results_distance_histogram,
3543                    "button_view_distance_histogram": self._view.ui.btn_view_distance_histogram,
3544                    "label_results_distance_table": self._view.ui.lbl_results_distance_table,
3545                    "button_view_distance_table": self._view.ui.btn_view_distance_table,
3546                    "label_results_structure_alignment": self._view.ui.lbl_results_structure_alignment,
3547                    "button_view_struct_alignment": self._view.ui.btn_view_struct_alignment,
3548                    "label_results_interest_regions": self._view.ui.lbl_results_interest_regions,
3549                    "list_results_interest_regions": self._view.ui.list_results_interest_regions,
3550                    "button_results_interest_regions": self._view.ui.btn_view_interesting_region,
3551                },
3552                {
3553                    "": None,
3554                },
3555            ),
3556        ]
3557        self.results_management = gui_page_management.GuiPageManagement(tmp_stages)
3558
3559    # </editor-fold>
3560
3561    # <editor-fold desc="Page init functions">
3562    def _init_fill_combo_boxes(self) -> None:
3563        """Fills all combo boxes of the plugin."""
3564        item_list_representation = [
3565            "",
3566            "cartoon",
3567            "ribbon",
3568        ]
3569        gui_utils.fill_combo_box(self._view.ui.box_representation, item_list_representation)
3570        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_representation, item_list_representation)
3571        # combo box BgColor
3572        item_list_bg_color = [
3573            "",
3574            "black",
3575            "white",
3576        ]
3577        gui_utils.fill_combo_box(self._view.ui.box_bg_color, item_list_bg_color)
3578        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_bg_color, item_list_bg_color)
3579        # combo box Renderer
3580        item_list_renderer = [
3581            "",
3582            "default renderer",
3583            "PyMOL internal renderer",
3584        ]
3585        gui_utils.fill_combo_box(self._view.ui.box_renderer, item_list_renderer)
3586        # combo box RayTraceMode
3587        item_list_ray_trace_mode = [
3588            "",
3589            "normal color",
3590            "normal color + black outline",
3591            "black outline only",
3592            "quantized color + black outline",
3593        ]
3594        gui_utils.fill_combo_box(self._view.ui.box_ray_trace_mode, item_list_ray_trace_mode)
3595        # combo box Ray Texture
3596        item_list_ray_texture = [
3597            "",
3598            "None",
3599            "Matte 1",
3600            "Matte 2",
3601            "Swirl 1",
3602            "Fiber",
3603        ]
3604        gui_utils.fill_combo_box(self._view.ui.box_ray_texture, item_list_ray_texture)
3605        # combo box protein Colors
3606        gui_utils.fill_combo_box(self._view.ui.box_manage_choose_color, constants.PYMOL_COLORS)
3607
3608    def _init_new_page(self) -> None:
3609        """Clears all text fields and hides everything which is needed."""
3610        self._view.ui.txt_new_project_name.clear()
3611        self._view.ui.txt_new_choose_reference.clear()
3612        self._view.ui.lbl_new_status_project_name.setText("")
3613        self._view.ui.lbl_new_status_choose_reference.setText("")
3614        self._view.ui.cb_new_add_reference.setCheckState(0)
3615        self._view.ui.btn_new_create_project.setEnabled(False)
3616        styles.color_button_not_ready(self._view.ui.btn_new_create_project)
3617
3618    def _init_use_page(self) -> None:
3619        """Clears all text fields and hides everything which is needed."""
3620        gui_elements = [
3621            self._view.ui.lbl_use_search,
3622            self._view.ui.lbl_use_status_search,
3623            self._view.ui.txt_use_search,
3624            self._view.ui.btn_use_add_available_protein_structures,
3625            self._view.ui.lbl_use_available_protein_structures,
3626            self._view.ui.list_use_available_protein_structures,
3627            self._view.ui.btn_use_remove_selected_protein_structures,
3628            self._view.ui.lbl_use_selected_protein_structures,
3629            self._view.ui.list_use_selected_protein_structures,
3630            self._view.ui.btn_use_back,
3631            self._view.ui.btn_use_create_new_project,
3632            self._view.ui.lbl_use_new_project,
3633        ]
3634        gui_utils.hide_gui_elements(gui_elements)
3635        self._view.ui.txt_use_project_name.clear()
3636        self._view.ui.lbl_use_status_project_name.setText("")
3637        self._view.ui.txt_use_search.clear()
3638        self._view.ui.lbl_use_status_search.setText("")
3639        self._view.ui.list_use_available_protein_structures.clear()
3640        self._view.ui.list_use_selected_protein_structures.clear()
3641        self._view.ui.list_use_existing_projects.clear()
3642        self._view.ui.btn_use_next.setEnabled(False)
3643        self.hide_protein_selection_for_use()
3644
3645    def _init_edit_page(self) -> None:
3646        """Clears all text fields and hides everything which is needed."""
3647        self._view.ui.list_edit_project_proteins.clear()
3648        gui_elements_to_hide = [
3649            self._view.ui.lbl_edit_clean_new_prot,
3650            self._view.ui.btn_edit_clean_new_prot,
3651            self._view.ui.lbl_edit_clean_update_prot,
3652            self._view.ui.btn_edit_clean_update_prot,
3653            self._view.ui.label_12,
3654            self._view.ui.btn_edit_project_delete,
3655            self._view.ui.label_15,
3656            self._view.ui.btn_edit_protein_rename,
3657            self._view.ui.btn_edit_project_save,
3658            self._view.ui.label_13,
3659        ]
3660        gui_utils.hide_gui_elements(gui_elements_to_hide)
3661        gui_utils.fill_list_view_with_protein_names(self._current_project, self._view.ui.list_edit_project_proteins)
3662        # self.project_scanner.scan_project_for_valid_proteins(self._view.ui.list_edit_project_proteins)
3663
3664    def _init_sequence_vs_pdb_page(self) -> None:
3665        """Clears all text fields and hides everything which is needed."""
3666        self._view.ui.list_s_v_p_ref_chains.clear()
3667        # # sets up defaults: Prediction + Analysis
3668        #
3669        # #self._view.ui.label_18.hide()
3670        # #self._view.ui.txt_prediction_project_name.hide()
3671        # #self._view.ui.lbl_prediction_status_project_name.hide()
3672        # # stage 1
3673        # self._view.ui.lbl_prediction_status_project_name.setText("")
3674        #
3675        # #self._view.ui.list_widget_projects.hide()
3676        # #self._view.ui.btn_prediction_next_1.hide()
3677        # # stage 2
3678        # self._view.ui.lbl_prediction_load_reference.hide()
3679        # self._view.ui.txt_prediction_load_reference.clear()
3680        # self._view.ui.txt_prediction_load_reference.hide()
3681        # self._view.ui.lbl_prediction_status_load_reference.setText("")
3682        # self._view.ui.btn_prediction_back_2.setEnabled(False)
3683        # self._view.ui.btn_prediction_back_2.hide()
3684        # self._view.ui.btn_prediction_next_2.setEnabled(False)
3685        # self._view.ui.btn_prediction_next_2.hide()
3686        #
3687        # # stage 3
3688        # self._view.ui.lbl_prediction_ref_chains.hide()
3689        # self._view.ui.list_widget_ref_chains.hide()
3690        # # TO-DO: stylesheet needs to be integrated into the styles.css
3691        # self._view.ui.list_widget_ref_chains.setStyleSheet("border-style: solid;"
3692        #                                              "border-width: 2px;"
3693        #                                              "border-radius: 8px;"
3694        #                                              "border-color: #DCDBE3;")
3695        # self._view.ui.list_widget_ref_chains.setSelectionMode(PyQt5.QtWidgets.QAbstractItemView.ExtendedSelection)
3696        # self._view.ui.btn_prediction_back_3.setEnabled(False)
3697        # self._view.ui.btn_prediction_back_3.hide()
3698        # self._view.ui.btn_prediction_start.setEnabled(False)
3699        # self._view.ui.btn_prediction_start.hide()
3700        # # TO-DO: needs to be removed if model chains are implemented at the right spot
3701        # self._view.ui.lbl_prediction_model_chains.hide()
3702        # self._view.ui.txt_prediction_chain_model.hide()
3703
3704    def _init_results_page(self) -> None:
3705        """Clears all text fields and hides everything which is needed."""
3706        # stage 1
3707        self._view.ui.list_results_interest_regions.clear()
3708        self._view.ui.txt_results_rmsd.clear()
3709        self._view.ui.txt_results_aligned_residues.clear()
3710
3711    def _init_analysis_image_page(self) -> None:
3712        """Clears all text fields and hides everything which is needed."""
3713        self._view.ui.list_analysis_images_struct_analysis.setEnabled(True)
3714        self._view.ui.list_analysis_images_creation_struct_analysis.setEnabled(True)
3715        self.display_image_analysis_page()
3716
3717    def _init_image_page(self) -> None:
3718        """Hides everything which is needed."""
3719        self._view.ui.label_10.hide()
3720        self._view.ui.box_ray_trace_mode.hide()
3721        self._view.ui.label_14.hide()
3722        self._view.ui.box_ray_texture.hide()
3723
3724    def _init_batch_analysis_page(self) -> None:
3725        """Clears all text fields and hides everything which is needed."""
3726        # sets up defaults: Batch
3727        self.batch_analysis_management.show_stage_x(0)
3728        self._view.ui.list_analysis_batch_overview.clear()
3729        self._view.ui.btn_analysis_batch_remove.hide()
3730
3731    def _init_all_pages(self) -> None:
3732        """Collection of all init methods to reset all page defaults."""
3733        self._init_local_pred_mono_page()
3734        self._init_local_pred_multi_page()
3735        self._init_mono_pred_analysis_page()
3736        self._init_multi_pred_analysis_page()
3737        self._init_sequence_vs_pdb_page()
3738        self._init_batch_analysis_page()
3739        self._init_analysis_image_page()
3740        self._init_results_page()
3741        self._init_image_page()
3742
3743    # </editor-fold>
3744
3745    # <editor-fold desc="Display page functions">
3746    def display_home_page(self) -> None:
3747        """Displays the homepage of the plugin."""
3748        if self.is_distance_plot_open:
3749            self.distance_plot_dialog.close()
3750            self.is_distance_plot_open = False
3751        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 0, "Home")
3752
3753    def display_job_analysis_page(self) -> None:
3754        """Displays the job analysis work area."""
3755        self._view.ui.list_analysis_batch_ref_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3756        self._view.ui.list_analysis_batch_model_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3757        # regular work area opening
3758        self._init_batch_analysis_page()
3759        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 4, "Structure Analysis")
3760        self.last_sidebar_button = styles.color_sidebar_buttons(
3761            self.last_sidebar_button,
3762            self._view.ui.btn_batch_analysis_page,
3763        )
3764
3765    def display_results_page(self) -> None:
3766        """Displays the results work area."""
3767        if self.is_distance_plot_open:
3768            self.distance_plot_dialog.close()
3769            self.is_distance_plot_open = False
3770        results = []
3771        results.insert(0, "")
3772
3773        for tmp_protein_pair in self._current_project.protein_pairs:
3774            results.append(tmp_protein_pair.name)
3775            if tmp_protein_pair.name == self.results_name:
3776                pass
3777        self._view.ui.cb_results_analysis_options.clear()
3778        gui_utils.fill_combo_box(self._view.ui.cb_results_analysis_options, results)
3779
3780        desired_string: str = self.main_window_state.results_page.results_name
3781        # Find the index of the string in the combo box
3782        index = self._view.ui.cb_results_analysis_options.findText(desired_string)
3783        # Set the current index of the combo box
3784        if index != -1:
3785            self._view.ui.cb_results_analysis_options.setCurrentIndex(index)
3786        else:
3787            print(f"String '{desired_string}' not found in the combo box.")
3788
3789        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 5, "Results")
3790        self.last_sidebar_button = styles.color_sidebar_buttons(
3791            self.last_sidebar_button,
3792            self._view.ui.btn_results_page,
3793        )
3794
3795    def display_image_page(self) -> None:
3796        """Displays the image work area."""
3797        if self.is_distance_plot_open:
3798            self.distance_plot_dialog.close()
3799            self.is_distance_plot_open = False
3800        self._init_image_page()
3801
3802        if self.main_window_state.image_page.transparent_background:
3803            self._view.ui.cb_transparent_bg.setChecked(True)
3804        else:
3805            self._view.ui.cb_transparent_bg.setChecked(False)
3806        if self.main_window_state.image_page.ray_tracing:
3807            self._view.ui.cb_ray_tracing.setChecked(True)
3808        else:
3809            self._view.ui.cb_ray_tracing.setChecked(False)
3810        try:
3811            self._view.ui.box_representation.setCurrentIndex(
3812                self._view.ui.box_representation.findText(self.main_window_state.image_page.representation),
3813            )
3814            self._view.ui.box_bg_color.setCurrentIndex(
3815                self._view.ui.box_bg_color.findText(self.main_window_state.image_page.background_color),
3816            )
3817            self._view.ui.box_renderer.setCurrentIndex(self.main_window_state.image_page.renderer)
3818            self._view.ui.box_ray_trace_mode.setCurrentIndex(self.main_window_state.image_page.ray_trace_mode)
3819            self._view.ui.box_ray_texture.setCurrentIndex(self.main_window_state.image_page.ray_texture)
3820        except IndexError:
3821            constants.PYSSA_LOGGER.error("An option is invalid.")
3822
3823        if self._view.ui.box_renderer.currentText() == "":
3824            self._view.ui.cb_ray_tracing.hide()
3825            self._view.ui.label_26.hide()
3826        else:
3827            self._view.ui.cb_ray_tracing.show()
3828            self._view.ui.label_26.show()
3829
3830        if self._view.ui.cb_ray_tracing.isChecked():
3831            self._view.ui.label_10.show()
3832            self._view.ui.box_ray_trace_mode.show()
3833            self._view.ui.label_14.show()
3834            self._view.ui.box_ray_texture.show()
3835        else:
3836            self._view.ui.label_10.hide()
3837            self._view.ui.box_ray_trace_mode.hide()
3838            self._view.ui.label_14.hide()
3839            self._view.ui.box_ray_texture.hide()
3840
3841        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_image_page)
3842        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 6, "Image")
3843
3844    def display_new_page(self) -> None:
3845        """Displays the new project work area."""
3846        self._init_new_page()
3847        self._view.ui.list_new_projects.clear()
3848        # pre-process
3849        gui_elements_to_hide = [
3850            self._view.ui.lbl_new_choose_reference,
3851            self._view.ui.txt_new_choose_reference,
3852            self._view.ui.btn_new_choose_reference,
3853        ]
3854        gui_utils.hide_gui_elements(gui_elements_to_hide)
3855        self._view.status_bar.showMessage(self._workspace_label.text())
3856        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_new_projects)
3857        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 7, "Create new project")
3858        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_new_page)
3859
3860    def display_open_page(self) -> None:
3861        """Displays the open project work area."""
3862        self._view.ui.txt_open_search.clear()
3863        self._view.ui.txt_open_selected_project.clear()
3864        if safeguard.Safeguard.check_filepath(self._workspace_path):
3865            self._view.ui.list_open_projects.clear()
3866            # pre-process
3867            self._view.status_bar.showMessage(self._workspace_label.text())
3868            try:
3869                tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_open_projects)
3870            except PermissionError:
3871                gui_utils.error_dialog_settings(
3872                    "The settings file is corrupted. Please restore the settings!",
3873                    "",
3874                    self._application_settings,
3875                )
3876                self.display_home_page()
3877                return
3878            tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 8, "Open existing project")
3879            self.last_sidebar_button = styles.color_sidebar_buttons(
3880                self.last_sidebar_button,
3881                self._view.ui.btn_open_page,
3882            )
3883        else:
3884            gui_utils.error_dialog_settings(
3885                "The settings file is corrupted. Please restore the settings!",
3886                "",
3887                self._application_settings,
3888            )
3889            self.display_home_page()
3890
3891    def display_delete_page(self) -> None:
3892        """Displays the "delete" project work area."""
3893        self._view.ui.txt_delete_search.clear()
3894        self._view.ui.txt_delete_selected_projects.clear()
3895        self._view.ui.list_delete_projects.clear()
3896        # pre-process
3897        self._view.status_bar.showMessage(self._workspace_label.text())
3898        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
3899        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 9, "Delete existing project")
3900        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_delete_page)
3901
3902    def display_edit_page(self) -> None:
3903        """Displays the edit project page."""
3904        if self.is_distance_plot_open:
3905            self.distance_plot_dialog.close()
3906            self.is_distance_plot_open = False
3907        # pre-process
3908        self._view.status_bar.showMessage(self._workspace_label.text())
3909        self._init_edit_page()
3910        tools.switch_page(
3911            self._view.ui.stackedWidget,
3912            self._view.ui.lbl_page_title,
3913            13,
3914            "Edit proteins of current project",
3915        )
3916        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_edit_page)
3917        if len(self._view.ui.list_edit_project_proteins) >= 2:
3918            self._view.ui.btn_edit_existing_protein_struct.hide()
3919            self._view.ui.lbl_edit_existing_protein_struct.hide()
3920        else:
3921            self._view.ui.btn_edit_existing_protein_struct.show()
3922            self._view.ui.lbl_edit_existing_protein_struct.show()
3923
3924    def display_hotspots_page(self) -> None:
3925        """Displays the hotspots page."""
3926        if self.is_distance_plot_open:
3927            self.distance_plot_dialog.close()
3928            self.is_distance_plot_open = False
3929        try:
3930            print(self._view.ui.list_hotspots_choose_protein.currentItem().text())
3931        except AttributeError:
3932            self._view.ui.list_hotspots_choose_protein.clear()
3933            gui_elements_to_hide = [
3934                self._view.ui.lbl_hotspots_resi_no,
3935                self._view.ui.sp_hotspots_resi_no,
3936                self._view.ui.lbl_hotspots_resi_show,
3937                self._view.ui.btn_hotspots_resi_show,
3938                self._view.ui.lbl_hotspots_resi_hide,
3939                self._view.ui.btn_hotspots_resi_hide,
3940                self._view.ui.lbl_hotspots_resi_zoom,
3941                self._view.ui.btn_hotspots_resi_zoom,
3942            ]
3943            gui_utils.hide_gui_elements(gui_elements_to_hide)
3944            gui_utils.fill_list_view_with_protein_names(
3945                self._current_project,
3946                self._view.ui.list_hotspots_choose_protein,
3947            )
3948            gui_utils.fill_list_view_with_protein_pair_names(
3949                self._current_project,
3950                self._view.ui.list_hotspots_choose_protein,
3951            )
3952        # self.project_scanner.scan_project_for_valid_proteins(self._view.ui.list_hotspots_choose_protein)
3953        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 18, "Hotspots")
3954        self.last_sidebar_button = styles.color_sidebar_buttons(
3955            self.last_sidebar_button,
3956            self._view.ui.btn_hotspots_page,
3957        )
3958
3959    def display_manage_pymol_session(self) -> None:
3960        """Displays the manage pymol session page."""
3961        if self.is_distance_plot_open:
3962            self.distance_plot_dialog.close()
3963            self.is_distance_plot_open = False
3964        self._view.ui.box_manage_choose_protein.clear()
3965        pymol_objs = cmd.get_object_list()
3966        pymol_objs.insert(0, "")
3967        for tmp_object in pymol_objs:
3968            self._view.ui.box_manage_choose_protein.addItem(tmp_object)
3969        self._view.ui.box_manage_choose_protein.setCurrentIndex(
3970            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_PROTEIN][0],
3971        )
3972        self._view.ui.box_manage_choose_color.setCurrentIndex(
3973            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_COLOR][0],
3974        )
3975        self._view.ui.box_manage_choose_representation.setCurrentIndex(
3976            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_REPRESENTATION][0],
3977        )
3978        self._view.ui.box_manage_choose_bg_color.setCurrentIndex(
3979            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_BG_COLOR][0],
3980        )
3981        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 24, "Manage PyMOL session")
3982        self.last_sidebar_button = styles.color_sidebar_buttons(
3983            self.last_sidebar_button,
3984            self._view.ui.btn_manage_session,
3985        )
3986        gui_elements_to_hide = [
3987            self._view.ui.lbl_manage_choose_color,
3988            self._view.ui.box_manage_choose_color,
3989            self._view.ui.lbl_manage_choose_representation,
3990            self._view.ui.box_manage_choose_representation,
3991            self._view.ui.lbl_manage_choose_bg_color,
3992            self._view.ui.box_manage_choose_bg_color,
3993            self._view.ui.lbl_disulfid_bond_1,
3994            self._view.ui.lbl_disulfid_bond_2,
3995            self._view.ui.btn_disulfid_bond_show,
3996            self._view.ui.btn_disulfid_bond_hide,
3997        ]
3998        gui_utils.hide_gui_elements(gui_elements_to_hide)
3999
4000    # </editor-fold>
4001
4002    # <editor-fold desc="New project">
4003    def show_add_reference(self) -> None:
4004        """Shows the reference input section."""
4005        # checkbox is checked
4006        self._view.ui.cb_new_add_reference.checkState()
4007        if self._view.ui.cb_new_add_reference.checkState() == 2:
4008            self._view.ui.txt_new_choose_reference.clear()
4009            self._view.ui.txt_new_choose_reference.setStyleSheet("background-color: white")
4010            self._view.ui.lbl_new_choose_reference.show()
4011            self._view.ui.txt_new_choose_reference.show()
4012            self._view.ui.btn_new_choose_reference.show()
4013            self._view.ui.btn_new_create_project.setEnabled(False)
4014            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4015            # check internet connectivity
4016            if not tools.check_internet_connectivity():
4017                gui_utils.no_internet_dialog()
4018                self._view.ui.txt_new_choose_reference.setEnabled(False)
4019                self._view.ui.lbl_new_status_choose_reference.setText("You cannot enter a PDB ID (no internet).")
4020                return
4021            self._view.ui.txt_new_choose_reference.setEnabled(True)
4022            self._view.ui.lbl_new_status_choose_reference.setText("")
4023        else:
4024            self._view.ui.lbl_new_choose_reference.hide()
4025            self._view.ui.txt_new_choose_reference.hide()
4026            self._view.ui.btn_new_choose_reference.hide()
4027            self._view.ui.lbl_new_status_choose_reference.setText("")
4028            self._view.ui.btn_new_create_project.setEnabled(True)
4029
4030    def load_reference_in_project(self) -> None:
4031        """Loads a reference in a new project."""
4032        try:
4033            # open file dialog
4034            file_name = QtWidgets.QFileDialog.getOpenFileName(
4035                self._view,
4036                "Open Reference",
4037                QtCore.QDir.homePath(),
4038                "PDB Files (*.pdb)",
4039            )
4040            if file_name == ("", ""):
4041                raise ValueError
4042            # display path in text box
4043            self._view.ui.txt_new_choose_reference.setText(str(file_name[0]))
4044            self._view.ui.txt_new_choose_reference.setEnabled(False)
4045            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4046            self._view.ui.btn_new_create_project.setEnabled(True)
4047        except ValueError:
4048            print("No file has been selected.")
4049
4050    def validate_reference_in_project(self) -> None:
4051        """Checks if the entered reference protein is valid or not."""
4052        if len(self._view.ui.txt_new_choose_reference.text()) == 0:
4053            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4054            self._view.ui.lbl_new_status_choose_reference.setText("")
4055            self._view.ui.btn_new_create_project.setEnabled(False)
4056            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4057        elif len(self._view.ui.txt_new_choose_reference.text()) < 4:
4058            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4059            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4060            self._view.ui.btn_new_create_project.setEnabled(False)
4061            self._view.ui.lbl_new_status_choose_reference.setText("")
4062        # checks if a pdb id was entered
4063        elif len(self._view.ui.txt_new_choose_reference.text()) == 4:
4064            pdb_id = self._view.ui.txt_new_choose_reference.text().upper()
4065            try:
4066                # the pdb file gets saved in a scratch directory where it gets deleted immediately
4067                cmd.fetch(pdb_id, type="pdb", path=constants.SCRATCH_DIR)
4068                os.remove(f"{constants.SCRATCH_DIR}/{pdb_id}.pdb")
4069                cmd.reinitialize()
4070                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4071                self._view.ui.btn_new_create_project.setEnabled(True)
4072            # if the id does not exist an exception gets raised
4073            except pymol.CmdException:
4074                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4075                return
4076            except FileNotFoundError:
4077                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4078                self._view.ui.lbl_new_status_choose_reference.setText("Invalid PDB ID.")
4079                self._view.ui.btn_new_create_project.setEnabled(False)
4080                return
4081        else:
4082            if self._view.ui.txt_new_choose_reference.text().find("/") == -1:
4083                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4084                self._view.ui.btn_new_create_project.setEnabled(False)
4085                styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4086
4087            elif self._view.ui.txt_new_choose_reference.text().find("\\") == -1:
4088                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4089                self._view.ui.btn_new_create_project.setEnabled(False)
4090                styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4091
4092    def validate_project_name(self) -> None:
4093        """Validates the input of the project name in real-time."""
4094        input_validator.InputValidator.validate_project_name(
4095            self._view.ui.list_new_projects,
4096            self._view.ui.txt_new_project_name,
4097            self._view.ui.lbl_new_status_project_name,
4098            self._view.ui.btn_new_create_project,
4099            self._view.ui.cb_new_add_reference,
4100        )
4101
4102    # </editor-fold>
4103
4104    # <editor-fold desc="Open project">
4105    def validate_open_search(self) -> None:
4106        """Validates the input of the project name in real-time."""
4107        if self._view.ui.list_open_projects.currentItem() is not None:
4108            self._view.ui.list_open_projects.currentItem().setSelected(False)
4109        # set color for lineEdit
4110        input_validator.InputValidator.validate_search_input(
4111            self._view.ui.list_open_projects,
4112            self._view.ui.txt_open_search,
4113            self._view.ui.lbl_open_status_search,
4114            self._view.ui.txt_open_selected_project,
4115        )
4116
4117    def select_project_from_open_list(self) -> None:
4118        """Sets the selected project name in the text box."""
4119        try:
4120            self._view.ui.txt_open_selected_project.setText(self._view.ui.list_open_projects.currentItem().text())
4121        except AttributeError:
4122            self._view.ui.txt_open_selected_project.setText("")
4123
4124    def activate_open_button(self) -> None:
4125        """Activates the open button."""
4126        if self._view.ui.txt_open_selected_project.text() == "":
4127            self._view.ui.btn_open_open_project.setEnabled(False)
4128        else:
4129            self._view.ui.btn_open_open_project.setEnabled(True)
4130
4131    # </editor-fold>
4132
4133    # <editor-fold desc="Delete project">
4134    def select_project_from_delete_list(self) -> None:
4135        """Selects a project from the project list on the delete page."""
4136        try:
4137            self._view.ui.txt_delete_selected_projects.setText(self._view.ui.list_delete_projects.currentItem().text())
4138        except AttributeError:
4139            self._view.ui.txt_delete_selected_projects.setText("")
4140
4141    def activate_delete_button(self) -> None:
4142        """Activates the delete button."""
4143        if self._view.ui.txt_delete_selected_projects.text() == "":
4144            self._view.ui.btn_delete_delete_project.setEnabled(False)
4145        else:
4146            self._view.ui.btn_delete_delete_project.setEnabled(True)
4147
4148    def validate_delete_search(self) -> None:
4149        """Validates the input of the project name in real-time."""
4150        if self._view.ui.list_delete_projects.currentItem() is not None:
4151            self._view.ui.list_delete_projects.currentItem().setSelected(False)
4152        # set color for lineEdit
4153        input_validator.InputValidator.validate_search_input(
4154            self._view.ui.list_delete_projects,
4155            self._view.ui.txt_delete_search,
4156            self._view.ui.lbl_delete_status_search,
4157            self._view.ui.txt_delete_selected_projects,
4158        )
4159
4160    # </editor-fold>
4161
4162    # <editor-fold desc="View page">
4163    def display_view_page(self) -> None:
4164        """Displays the edit project page."""
4165        if self.is_distance_plot_open:
4166            self.distance_plot_dialog.close()
4167            self.is_distance_plot_open = False
4168        self._view.ui.list_view_project_proteins.clear()
4169        self._view.ui.txtedit_view_sequence.clear()
4170        # pre-process
4171        self._view.status_bar.showMessage(self._workspace_label.text())
4172        # list all proteins from pdb directory
4173        gui_utils.fill_list_view_with_protein_names(self._current_project, self._view.ui.list_view_project_proteins)
4174
4175        tools.switch_page(
4176            self._view.ui.stackedWidget,
4177            self._view.ui.lbl_page_title,
4178            11,
4179            "View proteins of current project",
4180        )
4181        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_view_page)
4182        gui_elements_to_hide = [
4183            self._view.ui.btn_view_project_show,
4184            self._view.ui.btn_view_project_show_structure,
4185            self._view.ui.txtedit_view_sequence,
4186            self._view.ui.label_9,
4187            self._view.ui.label_11,
4188        ]
4189        gui_utils.hide_gui_elements(gui_elements_to_hide)
4190
4191    def view_show_options(self) -> None:
4192        """Controls which gui elements get shown."""
4193        gui_elements_to_show = [
4194            # self._view.ui.btn_view_project_show,
4195            self._view.ui.btn_view_project_show_structure,
4196            self._view.ui.txtedit_view_sequence,
4197            # self._view.ui.label_9,
4198            self._view.ui.label_11,
4199        ]
4200        gui_utils.show_gui_elements(gui_elements_to_show)
4201        self.view_sequence()
4202
4203    def view_sequence(self) -> None:
4204        """Displays the sequence of the selected protein in a text box."""
4205        tmp_protein_basename = self._view.ui.list_view_project_proteins.currentItem().text()
4206        tmp_protein_sequences = self._current_project.search_protein(tmp_protein_basename).get_protein_sequences()
4207        self._view.ui.txtedit_view_sequence.clear()
4208        for tmp_sequence in tmp_protein_sequences:
4209            self._view.ui.txtedit_view_sequence.append("".join(tmp_sequence.sequence))
4210        # fixme: experimental sequence viewer gui
4211        # dialog = dialog_sequence_viewer.SequenceViewer(tmp_protein_sequences, tmp_protein_filename)
4212        # dialog.exec_()
4213
4214    # </editor-fold>
4215
4216    # <editor-fold desc="Use page">
4217    def validate_use_project_name(self) -> None:
4218        """Validates the input of the project name in real-time."""
4219        input_validator.InputValidator.validate_project_name(
4220            self._view.ui.list_use_existing_projects,
4221            self._view.ui.txt_use_project_name,
4222            self._view.ui.lbl_use_status_project_name,
4223            self._view.ui.btn_use_next,
4224        )
4225
4226    def validate_use_search(self) -> None:
4227        """Validates the input of the protein name in real-time."""
4228        message = "Protein structure does not exists."
4229        input_validator.InputValidator.validate_search_input(
4230            self._view.ui.list_use_available_protein_structures,
4231            self._view.ui.txt_use_search,
4232            self._view.ui.lbl_use_status_search,
4233            status_message=message,
4234        )
4235
4236    def add_protein_structure_to_new_project(self) -> None:
4237        """Adds the selected protein to the list which is used to create the new project."""
4238        prot_to_add = self._view.ui.list_use_available_protein_structures.currentItem().text()
4239        self._view.ui.list_use_selected_protein_structures.addItem(prot_to_add)
4240        self._view.ui.list_use_available_protein_structures.takeItem(
4241            self._view.ui.list_use_available_protein_structures.currentRow(),
4242        )
4243        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4244        if self._view.ui.list_use_available_protein_structures.count() > 0:
4245            try:
4246                self._view.ui.list_use_available_protein_structures.currentItem().setSelected(False)
4247            except AttributeError:
4248                constants.PYSSA_LOGGER.debug("No selection in use available proteins list on Use page.")
4249
4250    def remove_protein_structure_to_new_project(self) -> None:
4251        """Removes the selected protein from the list which is used to create the new project."""
4252        prot_to_remove = self._view.ui.list_use_selected_protein_structures.currentItem()
4253        self._view.ui.list_use_selected_protein_structures.takeItem(
4254            self._view.ui.list_use_selected_protein_structures.currentRow(),
4255        )
4256        self._view.ui.list_use_available_protein_structures.addItem(prot_to_remove)
4257        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)
4258        if self._view.ui.list_use_selected_protein_structures.count() > 0:
4259            try:
4260                self._view.ui.list_use_selected_protein_structures.currentItem().setSelected(False)
4261            except AttributeError:
4262                constants.PYSSA_LOGGER.debug("No selection in use selected proteins list on Use page.")
4263
4264    def show_protein_selection_for_use(self) -> None:
4265        """Shows the two lists for the protein selection."""
4266        gui_elements_to_show = [
4267            self._view.ui.lbl_use_search,
4268            self._view.ui.lbl_use_status_search,
4269            self._view.ui.txt_use_search,
4270            self._view.ui.btn_use_add_available_protein_structures,
4271            self._view.ui.lbl_use_available_protein_structures,
4272            self._view.ui.list_use_available_protein_structures,
4273            self._view.ui.btn_use_remove_selected_protein_structures,
4274            self._view.ui.lbl_use_selected_protein_structures,
4275            self._view.ui.list_use_selected_protein_structures,
4276            self._view.ui.btn_use_back,
4277            self._view.ui.btn_use_create_new_project,
4278            self._view.ui.lbl_use_new_project,
4279        ]
4280        gui_utils.show_gui_elements(gui_elements_to_show)
4281        self._view.ui.txt_use_project_name.setEnabled(False)
4282        gui_elements_to_hide = [
4283            self._view.ui.btn_use_next,
4284            self._view.ui.list_use_existing_projects,
4285        ]
4286        gui_utils.hide_gui_elements(gui_elements_to_hide)
4287        gui_utils.disable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)
4288        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4289        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)
4290
4291    def hide_protein_selection_for_use(self) -> None:
4292        """Hides the two lists for the protein selection."""
4293        gui_elements_to_show = [
4294            self._view.ui.btn_use_next,
4295            self._view.ui.list_use_existing_projects,
4296        ]
4297        gui_utils.show_gui_elements(gui_elements_to_show)
4298        self._view.ui.txt_use_project_name.setEnabled(True)
4299
4300        gui_elements_to_hide = [
4301            self._view.ui.lbl_use_search,
4302            self._view.ui.lbl_use_status_search,
4303            self._view.ui.txt_use_search,
4304            self._view.ui.btn_use_add_available_protein_structures,
4305            self._view.ui.lbl_use_available_protein_structures,
4306            self._view.ui.list_use_available_protein_structures,
4307            self._view.ui.btn_use_remove_selected_protein_structures,
4308            self._view.ui.lbl_use_selected_protein_structures,
4309            self._view.ui.list_use_selected_protein_structures,
4310            self._view.ui.btn_use_back,
4311            self._view.ui.btn_use_create_new_project,
4312            self._view.ui.lbl_use_new_project,
4313        ]
4314        gui_utils.hide_gui_elements(gui_elements_to_hide)
4315        gui_utils.enable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)
4316
4317    def use_enable_add(self) -> None:
4318        """Enables the add button."""
4319        self._view.ui.btn_use_add_available_protein_structures.setEnabled(True)
4320
4321    def use_enable_remove(self) -> None:
4322        """Enables the remove button."""
4323        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(True)
4324
4325    # </editor-fold>
4326
4327    # <editor-fold desc="ESM fold">
4328    def _init_esm_pred_mono_page(self) -> None:
4329        """Clears all text boxes and sets up the default values for the page."""
4330        # clears everything
4331        self._view.ui.txt_esm_prot_name.clear()
4332        self._view.ui.txt_esm_prot_seq.clear()
4333        for i in range(self._view.ui.table_esm_prot_to_predict.rowCount()):
4334            self._view.ui.table_esm_prot_to_predict.removeRow(i)
4335        # sets up defaults: Prediction
4336        self._view.ui.btn_esm_next.setEnabled(False)
4337        self._view.ui.btn_esm_next_2.setEnabled(False)
4338        self._view.ui.lbl_esm_prot_name_status.setText("")
4339        self._view.ui.lbl_esm_prot_seq_status.setText("")
4340
4341    def display_esm_pred_mono(self) -> None:
4342        """Displays the esm_fold monomer page."""
4343        self._init_esm_pred_mono_page()
4344        gui_elements_to_show = [
4345            self._view.ui.lbl_esm_prot_to_predict,
4346            self._view.ui.table_esm_prot_to_predict,
4347            self._view.ui.btn_esm_seq_to_predict,
4348        ]
4349        gui_elements_to_hide = [
4350            self._view.ui.btn_esm_seq_to_predict_remove,
4351            self._view.ui.lbl_esm_prot_name,
4352            self._view.ui.txt_esm_prot_name,
4353            self._view.ui.lbl_esm_prot_name_status,
4354            self._view.ui.btn_esm_back,
4355            self._view.ui.btn_esm_next,
4356            self._view.ui.lbl_esm_prot_seq,
4357            self._view.ui.txt_esm_prot_seq,
4358            self._view.ui.lbl_esm_prot_seq_status,
4359            self._view.ui.btn_esm_back_2,
4360            self._view.ui.btn_esm_next_2,
4361            self._view.ui.btn_esm_predict,
4362        ]
4363        gui_utils.show_gui_elements(gui_elements_to_show)
4364        gui_utils.hide_gui_elements(gui_elements_to_hide)
4365        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4366        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 1, "ESMFold Monomer Prediction")
4367        self.last_sidebar_button = styles.color_sidebar_buttons(
4368            self.last_sidebar_button,
4369            self._view.ui.btn_pred_cloud_monomer_page,
4370        )
4371
4372    def cloud_esm_validate_protein_name(self) -> None:
4373        """Validates the input of the protein name in real-time."""
4374        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4375            self._view.ui.txt_esm_prot_name.text(),
4376            self._view.ui.table_esm_prot_to_predict,
4377        ):
4378            self._view.ui.lbl_esm_prot_name_status.setText("Protein name already used.")
4379            self._view.ui.btn_esm_next.setEnabled(False)
4380            styles.color_button_not_ready(self._view.ui.btn_esm_next)
4381        else:
4382            self._view.ui.btn_esm_next.setEnabled(True)
4383            tools.validate_protein_name(
4384                self._view.ui.txt_esm_prot_name,
4385                self._view.ui.lbl_esm_prot_name_status,
4386                self._view.ui.btn_esm_next,
4387            )
4388
4389    def cloud_esm_validate_protein_sequence(self) -> None:
4390        """Validates the input of the protein sequence in real-time."""
4391        tools.validate_protein_sequence(
4392            self._view.ui.txt_esm_prot_seq,
4393            self._view.ui.lbl_esm_prot_seq_status,
4394            self._view.ui.btn_esm_next_2,
4395        )
4396
4397    def setup_defaults_esm_monomer_prediction(self) -> None:
4398        """Sets up the default values for the page."""
4399        # clears everything
4400        self._view.ui.txt_esm_prot_name.clear()
4401        self._view.ui.txt_esm_prot_seq.clear()
4402        # sets up defaults: Prediction
4403        self._view.ui.btn_esm_next.setEnabled(False)
4404        self._view.ui.btn_esm_next_2.setEnabled(False)
4405        self._view.ui.lbl_esm_prot_name_status.setText("")
4406        self._view.ui.lbl_esm_prot_seq_status.setText("")
4407
4408    def cloud_esm_add_seq_to_predict(self) -> None:
4409        """Shows the gui elements to add a sequence to the protein to predict."""
4410        gui_elements_to_show = [
4411            self._view.ui.lbl_esm_prot_to_predict,
4412            self._view.ui.table_esm_prot_to_predict,
4413            self._view.ui.lbl_esm_prot_name,
4414            self._view.ui.txt_esm_prot_name,
4415            self._view.ui.lbl_esm_prot_name_status,
4416            self._view.ui.btn_esm_back,
4417            self._view.ui.btn_esm_next,
4418        ]
4419        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4420        gui_elements_to_hide = [
4421            self._view.ui.btn_esm_seq_to_predict_remove,
4422            self._view.ui.btn_esm_seq_to_predict,
4423            self._view.ui.lbl_esm_prot_seq,
4424            self._view.ui.txt_esm_prot_seq,
4425            self._view.ui.lbl_esm_prot_seq_status,
4426            self._view.ui.btn_esm_back_2,
4427            self._view.ui.btn_esm_next_2,
4428            self._view.ui.btn_esm_predict,
4429        ]
4430        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4431        gui_utils.show_gui_elements(gui_elements_to_show)
4432        gui_utils.hide_gui_elements(gui_elements_to_hide)
4433        self._view.ui.btn_esm_next.setEnabled(False)
4434        self._view.ui.txt_esm_prot_name.clear()
4435        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4436        if self._view.ui.table_esm_prot_to_predict.rowCount() > 0:
4437            try:
4438                self._view.ui.table_esm_prot_to_predict.currentItem().setSelected(False)
4439            except AttributeError:
4440                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
4441
4442    def cloud_esm_back(self) -> None:
4443        """Hides the gui elements for the protein name."""
4444        gui_elements_to_show = [
4445            self._view.ui.lbl_esm_prot_to_predict,
4446            self._view.ui.table_esm_prot_to_predict,
4447            self._view.ui.btn_esm_seq_to_predict_remove,
4448            self._view.ui.btn_esm_seq_to_predict,
4449        ]
4450        gui_elements_to_hide = [
4451            self._view.ui.lbl_esm_prot_name,
4452            self._view.ui.txt_esm_prot_name,
4453            self._view.ui.lbl_esm_prot_name_status,
4454            self._view.ui.btn_esm_back,
4455            self._view.ui.btn_esm_next,
4456            self._view.ui.lbl_esm_prot_seq,
4457            self._view.ui.txt_esm_prot_seq,
4458            self._view.ui.lbl_esm_prot_seq_status,
4459            self._view.ui.btn_esm_back_2,
4460            self._view.ui.btn_esm_next_2,
4461            self._view.ui.btn_esm_predict,
4462        ]
4463        gui_utils.show_gui_elements(gui_elements_to_show)
4464        gui_utils.hide_gui_elements(gui_elements_to_hide)
4465        self.cloud_esm_check_if_table_is_empty()
4466        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4467
4468    def cloud_esm_next(self) -> None:
4469        """Shows the gui elements for the protein name."""
4470        gui_elements_to_show = [
4471            self._view.ui.lbl_esm_prot_to_predict,
4472            self._view.ui.table_esm_prot_to_predict,
4473            self._view.ui.lbl_esm_prot_name,
4474            self._view.ui.txt_esm_prot_name,
4475            self._view.ui.lbl_esm_prot_seq,
4476            self._view.ui.txt_esm_prot_seq,
4477            self._view.ui.lbl_esm_prot_seq_status,
4478            self._view.ui.btn_esm_back_2,
4479            self._view.ui.btn_esm_next_2,
4480        ]
4481        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4482        gui_elements_to_hide = [
4483            self._view.ui.btn_esm_seq_to_predict_remove,
4484            self._view.ui.btn_esm_seq_to_predict,
4485            self._view.ui.lbl_esm_prot_name_status,
4486            self._view.ui.btn_esm_back,
4487            self._view.ui.btn_esm_next,
4488            self._view.ui.btn_esm_predict,
4489        ]
4490        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4491        gui_utils.show_gui_elements(gui_elements_to_show)
4492        gui_utils.hide_gui_elements(gui_elements_to_hide)
4493        self._view.ui.txt_esm_prot_seq.clear()
4494
4495    def cloud_esm_back_2(self) -> None:
4496        """Hides the gui elements for the protein sequence."""
4497        gui_elements_to_show = [
4498            self._view.ui.lbl_esm_prot_to_predict,
4499            self._view.ui.table_esm_prot_to_predict,
4500            self._view.ui.lbl_esm_prot_name,
4501            self._view.ui.txt_esm_prot_name,
4502            self._view.ui.lbl_esm_prot_name_status,
4503            self._view.ui.btn_esm_back,
4504            self._view.ui.btn_esm_next,
4505        ]
4506        gui_elements_to_hide = [
4507            self._view.ui.btn_esm_seq_to_predict_remove,
4508            self._view.ui.btn_esm_seq_to_predict,
4509            self._view.ui.lbl_esm_prot_seq,
4510            self._view.ui.txt_esm_prot_seq,
4511            self._view.ui.lbl_esm_prot_seq_status,
4512            self._view.ui.btn_esm_back_2,
4513            self._view.ui.btn_esm_next_2,
4514            self._view.ui.btn_esm_predict,
4515        ]
4516        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4517        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4518        gui_utils.show_gui_elements(gui_elements_to_show)
4519        gui_utils.hide_gui_elements(gui_elements_to_hide)
4520
4521    def cloud_esm_add_protein(self) -> None:
4522        """Adds protein to the list of proteins to predict."""
4523        self._view.ui.table_esm_prot_to_predict.setRowCount(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4524        self._view.ui.table_esm_prot_to_predict.insertRow(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4525        self._view.ui.table_esm_prot_to_predict.setItem(
4526            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4527            0,
4528            QtWidgets.QTableWidgetItem("A"),
4529        )
4530        self._view.ui.table_esm_prot_to_predict.setItem(
4531            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4532            1,
4533            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_seq.toPlainText()),
4534        )
4535        self._view.ui.table_esm_prot_to_predict.setVerticalHeaderItem(
4536            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4537            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_name.text()),
4538        )
4539        self._view.ui.table_esm_prot_to_predict.resizeColumnsToContents()
4540        self.cloud_esm_check_if_table_is_empty()
4541        gui_elements_to_show = [
4542            self._view.ui.lbl_esm_prot_to_predict,
4543            self._view.ui.table_esm_prot_to_predict,
4544            self._view.ui.btn_esm_seq_to_predict_remove,
4545            self._view.ui.btn_esm_seq_to_predict,
4546            self._view.ui.btn_esm_predict,
4547        ]
4548        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4549        gui_elements_to_hide = [
4550            self._view.ui.lbl_esm_prot_name,
4551            self._view.ui.txt_esm_prot_name,
4552            self._view.ui.lbl_esm_prot_name_status,
4553            self._view.ui.btn_esm_back,
4554            self._view.ui.btn_esm_next,
4555            self._view.ui.lbl_esm_prot_seq,
4556            self._view.ui.txt_esm_prot_seq,
4557            self._view.ui.lbl_esm_prot_seq_status,
4558            self._view.ui.btn_esm_back_2,
4559            self._view.ui.btn_esm_next_2,
4560        ]
4561        gui_utils.show_gui_elements(gui_elements_to_show)
4562        gui_utils.hide_gui_elements(gui_elements_to_hide)
4563        self._view.ui.btn_esm_predict.setEnabled(True)
4564        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4565        self.setup_defaults_esm_monomer_prediction()
4566
4567    def cloud_esm_remove(self) -> None:
4568        """Removes a protein from the list of proteins to predict."""
4569        self._view.ui.table_esm_prot_to_predict.removeRow(self._view.ui.table_esm_prot_to_predict.currentRow())
4570        gui_elements_to_show = [
4571            self._view.ui.lbl_esm_prot_to_predict,
4572            self._view.ui.table_esm_prot_to_predict,
4573            self._view.ui.btn_esm_seq_to_predict_remove,
4574            self._view.ui.btn_esm_seq_to_predict,
4575            self._view.ui.btn_esm_predict,
4576        ]
4577        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4578        gui_elements_to_hide = [
4579            self._view.ui.lbl_esm_prot_name,
4580            self._view.ui.txt_esm_prot_name,
4581            self._view.ui.lbl_esm_prot_name_status,
4582            self._view.ui.btn_esm_back,
4583            self._view.ui.btn_esm_next,
4584            self._view.ui.lbl_esm_prot_seq,
4585            self._view.ui.txt_esm_prot_seq,
4586            self._view.ui.lbl_esm_prot_seq_status,
4587            self._view.ui.btn_esm_back_2,
4588            self._view.ui.btn_esm_next_2,
4589        ]
4590        gui_utils.show_gui_elements(gui_elements_to_show)
4591        gui_utils.hide_gui_elements(gui_elements_to_hide)
4592        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4593        self.cloud_esm_check_if_table_is_empty()
4594
4595    def cloud_esm_item_changed(self) -> None:
4596        """Enables the remove button."""
4597        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(True)
4598
4599    def cloud_esm_check_if_table_is_empty(self) -> None:
4600        """Checks if the table proteins to predict is empty."""
4601        if self._view.ui.table_esm_prot_to_predict.rowCount() == 0:
4602            styles.color_button_not_ready(self._view.ui.btn_esm_predict)
4603            self._view.ui.btn_esm_predict.setEnabled(False)
4604            gui_elements_to_show = [
4605                self._view.ui.lbl_esm_prot_to_predict,
4606                self._view.ui.table_esm_prot_to_predict,
4607                self._view.ui.btn_esm_seq_to_predict,
4608            ]
4609            gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4610            gui_elements_to_hide = [
4611                self._view.ui.btn_esm_seq_to_predict_remove,
4612                self._view.ui.lbl_esm_prot_name,
4613                self._view.ui.txt_esm_prot_name,
4614                self._view.ui.lbl_esm_prot_name_status,
4615                self._view.ui.btn_esm_back,
4616                self._view.ui.btn_esm_next,
4617                self._view.ui.lbl_esm_prot_seq,
4618                self._view.ui.txt_esm_prot_seq,
4619                self._view.ui.lbl_esm_prot_seq_status,
4620                self._view.ui.btn_esm_back_2,
4621                self._view.ui.btn_esm_next_2,
4622                self._view.ui.btn_esm_predict,
4623            ]
4624            gui_utils.show_gui_elements(gui_elements_to_show)
4625            gui_utils.hide_gui_elements(gui_elements_to_hide)
4626        else:
4627            self._view.ui.btn_esm_predict.setEnabled(True)
4628
4629    # </editor-fold>
4630
4631    # <editor-fold desc="Monomer local prediction">
4632    def _init_local_pred_mono_page(self) -> None:
4633        """Clears all text boxes and sets default values for the gui elements."""
4634        # clears everything
4635        self._view.ui.txt_pred_mono_prot_name.clear()
4636        self._view.ui.txt_pred_mono_seq_name.clear()
4637        for i in range(self._view.ui.table_pred_mono_prot_to_predict.rowCount()):
4638            self._view.ui.table_pred_mono_prot_to_predict.removeRow(i)
4639        # sets up defaults: Prediction
4640        self._view.ui.btn_pred_mono_next.setEnabled(False)
4641        self._view.ui.btn_pred_mono_add_protein.setEnabled(False)
4642        self._view.ui.lbl_pred_mono_prot_name_status.setText("")
4643        self._view.ui.lbl_pred_mono_seq_name_status.setText("")
4644
4645    def display_local_pred_mono(self) -> None:
4646        """Displays the local prediction monomer page."""
4647        # checks internet connection
4648        if not tools.check_internet_connectivity():
4649            gui_utils.no_internet_dialog()
4650            return
4651        self._init_local_pred_mono_page()
4652        gui_elements_to_show = [
4653            self._view.ui.lbl_pred_mono_prot_to_predict,
4654            self._view.ui.table_pred_mono_prot_to_predict,
4655            self._view.ui.btn_pred_mono_seq_to_predict,
4656        ]
4657        gui_elements_to_hide = [
4658            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4659            self._view.ui.lbl_pred_mono_prot_name,
4660            self._view.ui.txt_pred_mono_prot_name,
4661            self._view.ui.lbl_pred_mono_prot_name_status,
4662            self._view.ui.btn_pred_mono_back,
4663            self._view.ui.btn_pred_mono_next,
4664            self._view.ui.lbl_pred_mono_seq_name,
4665            self._view.ui.txt_pred_mono_seq_name,
4666            self._view.ui.lbl_pred_mono_seq_name_status,
4667            self._view.ui.btn_pred_mono_back_2,
4668            self._view.ui.btn_pred_mono_add_protein,
4669            self._view.ui.lbl_pred_mono_advanced_config,
4670            self._view.ui.btn_pred_mono_advanced_config,
4671            self._view.ui.btn_pred_mono_predict,
4672        ]
4673        gui_utils.show_gui_elements(gui_elements_to_show)
4674        gui_utils.hide_gui_elements(gui_elements_to_hide)
4675        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4676        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 19, "Local Monomer Prediction")
4677        self.last_sidebar_button = styles.color_sidebar_buttons(
4678            self.last_sidebar_button,
4679            self._view.ui.btn_pred_local_monomer_page,
4680        )
4681
4682    def local_pred_mono_validate_protein_name(self) -> None:
4683        """Validates the input of the protein name in real-time."""
4684        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4685            self._view.ui.txt_pred_mono_prot_name.text(),
4686            self._view.ui.table_pred_mono_prot_to_predict,
4687        ):
4688            self._view.ui.lbl_pred_mono_prot_name_status.setText("Protein name already used.")
4689            self._view.ui.btn_pred_mono_next.setEnabled(False)
4690            styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4691        else:
4692            self._view.ui.btn_pred_mono_next.setEnabled(True)
4693            tools.validate_protein_name(
4694                self._view.ui.txt_pred_mono_prot_name,
4695                self._view.ui.lbl_pred_mono_prot_name_status,
4696                self._view.ui.btn_pred_mono_next,
4697            )
4698
4699    def local_pred_mono_validate_protein_sequence(self) -> None:
4700        """Validates the input of the protein sequence in real-time."""
4701        tools.validate_protein_sequence(
4702            self._view.ui.txt_pred_mono_seq_name,
4703            self._view.ui.lbl_pred_mono_seq_name_status,
4704            self._view.ui.btn_pred_mono_add_protein,
4705        )
4706
4707    def show_prediction_configuration(self) -> None:
4708        """Opens the prediction configuration dialog window."""
4709        config = dialog_advanced_prediction_configurations.DialogAdvancedPredictionConfigurations(
4710            self.prediction_configuration,
4711        )
4712        config.exec_()
4713        self.prediction_configuration.amber_force_field = config.prediction_config.amber_force_field
4714        self.prediction_configuration.templates = config.prediction_config.templates
4715
4716    def setup_defaults_monomer_prediction(self) -> None:
4717        """Sets up the defaults for the page."""
4718        # clears everything
4719        self._view.ui.txt_pred_mono_prot_name.clear()
4720        self._view.ui.txt_pred_mono_seq_name.clear()
4721        # sets up defaults: Prediction
4722        self._view.ui.btn_pred_mono_next.setEnabled(False)
4723        self._view.ui.btn_pred_mono_add_protein.setEnabled(False)
4724        self._view.ui.lbl_pred_mono_prot_name_status.setText("")
4725        self._view.ui.lbl_pred_mono_seq_name_status.setText("")
4726
4727    def local_pred_mono_add_seq_to_predict(self) -> None:
4728        """Shows the gui elements for the protein name."""
4729        gui_elements_to_show = [
4730            self._view.ui.lbl_pred_mono_prot_to_predict,
4731            self._view.ui.table_pred_mono_prot_to_predict,
4732            self._view.ui.lbl_pred_mono_prot_name,
4733            self._view.ui.txt_pred_mono_prot_name,
4734            self._view.ui.lbl_pred_mono_prot_name_status,
4735            self._view.ui.btn_pred_mono_back,
4736            self._view.ui.btn_pred_mono_next,
4737        ]
4738        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4739        gui_elements_to_hide = [
4740            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4741            self._view.ui.btn_pred_mono_seq_to_predict,
4742            self._view.ui.lbl_pred_mono_seq_name,
4743            self._view.ui.txt_pred_mono_seq_name,
4744            self._view.ui.lbl_pred_mono_seq_name_status,
4745            self._view.ui.btn_pred_mono_back_2,
4746            self._view.ui.btn_pred_mono_add_protein,
4747            self._view.ui.lbl_pred_mono_advanced_config,
4748            self._view.ui.btn_pred_mono_advanced_config,
4749            self._view.ui.btn_pred_mono_predict,
4750        ]
4751        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4752        gui_utils.show_gui_elements(gui_elements_to_show)
4753        gui_utils.hide_gui_elements(gui_elements_to_hide)
4754        self._view.ui.btn_pred_mono_next.setEnabled(False)
4755        self._view.ui.txt_pred_mono_prot_name.clear()
4756        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4757        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() > 0:
4758            try:
4759                self._view.ui.table_pred_mono_prot_to_predict.currentItem().setSelected(False)
4760            except AttributeError:
4761                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
4762
4763    def local_pred_mono_back(self) -> None:
4764        """Hides the gui elements for the protein name."""
4765        gui_elements_to_show = [
4766            self._view.ui.lbl_pred_mono_prot_to_predict,
4767            self._view.ui.table_pred_mono_prot_to_predict,
4768            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4769            self._view.ui.btn_pred_mono_seq_to_predict,
4770        ]
4771        gui_elements_to_hide = [
4772            self._view.ui.lbl_pred_mono_prot_name,
4773            self._view.ui.txt_pred_mono_prot_name,
4774            self._view.ui.lbl_pred_mono_prot_name_status,
4775            self._view.ui.btn_pred_mono_back,
4776            self._view.ui.btn_pred_mono_next,
4777            self._view.ui.lbl_pred_mono_seq_name,
4778            self._view.ui.txt_pred_mono_seq_name,
4779            self._view.ui.lbl_pred_mono_seq_name_status,
4780            self._view.ui.btn_pred_mono_back_2,
4781            self._view.ui.btn_pred_mono_add_protein,
4782            self._view.ui.lbl_pred_mono_advanced_config,
4783            self._view.ui.btn_pred_mono_advanced_config,
4784            self._view.ui.btn_pred_mono_predict,
4785        ]
4786        gui_utils.show_gui_elements(gui_elements_to_show)
4787        gui_utils.hide_gui_elements(gui_elements_to_hide)
4788        self.local_pred_mono_check_if_table_is_empty()
4789        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4790
4791    def local_pred_mono_next(self) -> None:
4792        """Shows the gui elements for the protein sequence."""
4793        gui_elements_to_show = [
4794            self._view.ui.lbl_pred_mono_prot_to_predict,
4795            self._view.ui.table_pred_mono_prot_to_predict,
4796            self._view.ui.lbl_pred_mono_prot_name,
4797            self._view.ui.txt_pred_mono_prot_name,
4798            self._view.ui.lbl_pred_mono_seq_name,
4799            self._view.ui.txt_pred_mono_seq_name,
4800            self._view.ui.lbl_pred_mono_seq_name_status,
4801            self._view.ui.btn_pred_mono_back_2,
4802            self._view.ui.btn_pred_mono_add_protein,
4803        ]
4804        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4805        gui_elements_to_hide = [
4806            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4807            self._view.ui.btn_pred_mono_seq_to_predict,
4808            self._view.ui.lbl_pred_mono_prot_name_status,
4809            self._view.ui.btn_pred_mono_back,
4810            self._view.ui.btn_pred_mono_next,
4811            self._view.ui.lbl_pred_mono_advanced_config,
4812            self._view.ui.btn_pred_mono_advanced_config,
4813            self._view.ui.btn_pred_mono_predict,
4814        ]
4815        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4816        gui_utils.show_gui_elements(gui_elements_to_show)
4817        gui_utils.hide_gui_elements(gui_elements_to_hide)
4818        self._view.ui.txt_pred_mono_seq_name.clear()
4819
4820    def local_pred_mono_back_2(self) -> None:
4821        """Hides the gui elements for the protein sequence."""
4822        gui_elements_to_show = [
4823            self._view.ui.lbl_pred_mono_prot_to_predict,
4824            self._view.ui.table_pred_mono_prot_to_predict,
4825            self._view.ui.lbl_pred_mono_prot_name,
4826            self._view.ui.txt_pred_mono_prot_name,
4827            self._view.ui.lbl_pred_mono_prot_name_status,
4828            self._view.ui.btn_pred_mono_back,
4829            self._view.ui.btn_pred_mono_next,
4830        ]
4831        gui_elements_to_hide = [
4832            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4833            self._view.ui.btn_pred_mono_seq_to_predict,
4834            self._view.ui.lbl_pred_mono_seq_name,
4835            self._view.ui.txt_pred_mono_seq_name,
4836            self._view.ui.lbl_pred_mono_seq_name_status,
4837            self._view.ui.btn_pred_mono_back_2,
4838            self._view.ui.btn_pred_mono_add_protein,
4839            self._view.ui.lbl_pred_mono_advanced_config,
4840            self._view.ui.btn_pred_mono_advanced_config,
4841            self._view.ui.btn_pred_mono_predict,
4842        ]
4843        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4844        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4845        gui_utils.show_gui_elements(gui_elements_to_show)
4846        gui_utils.hide_gui_elements(gui_elements_to_hide)
4847
4848    def local_pred_mono_add_protein(self) -> None:
4849        """Adds protein to the list of proteins to predict."""
4850        self._view.ui.table_pred_mono_prot_to_predict.setRowCount(
4851            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4852        )
4853        self._view.ui.table_pred_mono_prot_to_predict.insertRow(
4854            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4855        )
4856        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4857            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4858            0,
4859            QtWidgets.QTableWidgetItem("A"),
4860        )
4861        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4862            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4863            1,
4864            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_seq_name.toPlainText()),
4865        )
4866        self._view.ui.table_pred_mono_prot_to_predict.setVerticalHeaderItem(
4867            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4868            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_prot_name.text()),
4869        )
4870        self._view.ui.table_pred_mono_prot_to_predict.resizeColumnsToContents()
4871        self.local_pred_mono_check_if_table_is_empty()
4872        gui_elements_to_show = [
4873            self._view.ui.lbl_pred_mono_prot_to_predict,
4874            self._view.ui.table_pred_mono_prot_to_predict,
4875            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4876            self._view.ui.btn_pred_mono_seq_to_predict,
4877            self._view.ui.lbl_pred_mono_advanced_config,
4878            self._view.ui.btn_pred_mono_advanced_config,
4879            self._view.ui.btn_pred_mono_predict,
4880        ]
4881        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4882        gui_elements_to_hide = [
4883            self._view.ui.lbl_pred_mono_prot_name,
4884            self._view.ui.txt_pred_mono_prot_name,
4885            self._view.ui.lbl_pred_mono_prot_name_status,
4886            self._view.ui.btn_pred_mono_back,
4887            self._view.ui.btn_pred_mono_next,
4888            self._view.ui.lbl_pred_mono_seq_name,
4889            self._view.ui.txt_pred_mono_seq_name,
4890            self._view.ui.lbl_pred_mono_seq_name_status,
4891            self._view.ui.btn_pred_mono_back_2,
4892            self._view.ui.btn_pred_mono_add_protein,
4893        ]
4894        gui_utils.show_gui_elements(gui_elements_to_show)
4895        gui_utils.hide_gui_elements(gui_elements_to_hide)
4896        self._view.ui.btn_pred_mono_predict.setEnabled(True)
4897        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4898        self.setup_defaults_monomer_prediction()
4899
4900    def local_pred_mono_remove(self) -> None:
4901        """Removes the selected protein from the list of proteins to predict."""
4902        self._view.ui.table_pred_mono_prot_to_predict.removeRow(
4903            self._view.ui.table_pred_mono_prot_to_predict.currentRow(),
4904        )
4905        gui_elements_to_show = [
4906            self._view.ui.lbl_pred_mono_prot_to_predict,
4907            self._view.ui.table_pred_mono_prot_to_predict,
4908            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4909            self._view.ui.btn_pred_mono_seq_to_predict,
4910            self._view.ui.lbl_pred_mono_advanced_config,
4911            self._view.ui.btn_pred_mono_advanced_config,
4912            self._view.ui.btn_pred_mono_predict,
4913        ]
4914        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4915        gui_elements_to_hide = [
4916            self._view.ui.lbl_pred_mono_prot_name,
4917            self._view.ui.txt_pred_mono_prot_name,
4918            self._view.ui.lbl_pred_mono_prot_name_status,
4919            self._view.ui.btn_pred_mono_back,
4920            self._view.ui.btn_pred_mono_next,
4921            self._view.ui.lbl_pred_mono_seq_name,
4922            self._view.ui.txt_pred_mono_seq_name,
4923            self._view.ui.lbl_pred_mono_seq_name_status,
4924            self._view.ui.btn_pred_mono_back_2,
4925            self._view.ui.btn_pred_mono_add_protein,
4926        ]
4927        gui_utils.show_gui_elements(gui_elements_to_show)
4928        gui_utils.hide_gui_elements(gui_elements_to_hide)
4929        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4930        self.local_pred_mono_check_if_table_is_empty()
4931
4932    def local_pred_mono_item_changed(self) -> None:
4933        """Enables the remove button."""
4934        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(True)
4935
4936    def local_pred_mono_check_if_table_is_empty(self) -> None:
4937        """Checks if the table proteins to predict is empty."""
4938        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() == 0:
4939            styles.color_button_not_ready(self._view.ui.btn_pred_mono_predict)
4940            self._view.ui.btn_pred_mono_predict.setEnabled(False)
4941            gui_elements_to_show = [
4942                self._view.ui.lbl_pred_mono_prot_to_predict,
4943                self._view.ui.table_pred_mono_prot_to_predict,
4944                self._view.ui.btn_pred_mono_seq_to_predict,
4945            ]
4946            gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4947            gui_elements_to_hide = [
4948                self._view.ui.btn_pred_mono_seq_to_predict_remove,
4949                self._view.ui.lbl_pred_mono_prot_name,
4950                self._view.ui.txt_pred_mono_prot_name,
4951                self._view.ui.lbl_pred_mono_prot_name_status,
4952                self._view.ui.btn_pred_mono_back,
4953                self._view.ui.btn_pred_mono_next,
4954                self._view.ui.lbl_pred_mono_seq_name,
4955                self._view.ui.txt_pred_mono_seq_name,
4956                self._view.ui.lbl_pred_mono_seq_name_status,
4957                self._view.ui.btn_pred_mono_back_2,
4958                self._view.ui.btn_pred_mono_add_protein,
4959                self._view.ui.lbl_pred_mono_advanced_config,
4960                self._view.ui.btn_pred_mono_advanced_config,
4961                self._view.ui.btn_pred_mono_predict,
4962            ]
4963            gui_utils.show_gui_elements(gui_elements_to_show)
4964            gui_utils.hide_gui_elements(gui_elements_to_hide)
4965        else:
4966            self._view.ui.btn_pred_mono_predict.setEnabled(True)
4967
4968    # </editor-fold>
4969
4970    # <editor-fold desc="Multimer local prediction">
4971    def _init_local_pred_multi_page(self) -> None:
4972        """Clears all text boxes and sets default values for the gui elements."""
4973        # clears everything
4974        self._view.ui.txt_pred_multi_prot_name.clear()
4975        self._view.ui.txt_pred_multi_prot_seq.clear()
4976        self._view.ui.list_pred_multi_prot_seq_overview.clear()
4977        # sets up defaults: Prediction
4978        self._view.ui.btn_pred_multi_next.setEnabled(False)
4979        self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
4980        self._view.ui.lbl_pred_multi_prot_name_status.setText("")
4981        self._view.ui.lbl_pred_multi_prot_seq_status.setText("")
4982
4983    def display_local_pred_multi(self) -> None:
4984        """Displays the local prediction multimer page."""
4985        # checks internet connection
4986        if not tools.check_internet_connectivity():
4987            gui_utils.no_internet_dialog()
4988            return
4989
4990        gui_elements_to_show = [
4991            self._view.ui.lbl_pred_multi_prot_to_predict,
4992            self._view.ui.table_pred_multi_prot_to_predict,
4993            self._view.ui.btn_pred_multi_prot_to_predict_add,
4994        ]
4995        gui_elements_to_hide = [
4996            self._view.ui.btn_pred_multi_prot_to_predict_remove,
4997            self._view.ui.lbl_pred_multi_prot_name_status,
4998            self._view.ui.btn_pred_multi_back,
4999            self._view.ui.btn_pred_multi_next,
5000            self._view.ui.lbl_pred_multi_prot_name,
5001            self._view.ui.txt_pred_multi_prot_name,
5002            self._view.ui.lbl_pred_multi_prot_seq,
5003            self._view.ui.txt_pred_multi_prot_seq,
5004            self._view.ui.lbl_pred_multi_prot_seq_status,
5005            self._view.ui.lbl_pred_multi_prot_seq_add,
5006            self._view.ui.btn_pred_multi_prot_seq_add,
5007            self._view.ui.lbl_pred_multi_prot_seq_overview,
5008            self._view.ui.list_pred_multi_prot_seq_overview,
5009            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5010            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5011            self._view.ui.btn_pred_multi_back_2,
5012            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5013            self._view.ui.lbl_pred_multi_advanced_config,
5014            self._view.ui.btn_pred_multi_advanced_config,
5015            self._view.ui.btn_pred_multi_predict,
5016        ]
5017        for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1, -1, -1):
5018            self._view.ui.table_pred_multi_prot_to_predict.removeRow(i)
5019        gui_utils.show_gui_elements(gui_elements_to_show)
5020        gui_utils.hide_gui_elements(gui_elements_to_hide)
5021        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 20, "Local Multimer Prediction")
5022        self.last_sidebar_button = styles.color_sidebar_buttons(
5023            self.last_sidebar_button,
5024            self._view.ui.btn_pred_local_multimer_page,
5025        )
5026
5027    def local_pred_multi_validate_protein_name(self) -> None:
5028        """Validates the input of the protein name in real-time."""
5029        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5030            self._view.ui.txt_pred_multi_prot_name.text(),
5031            self._view.ui.table_pred_multi_prot_to_predict,
5032        ):
5033            self._view.ui.lbl_pred_multi_prot_name_status.setText("Protein name already used.")
5034            self._view.ui.btn_pred_multi_next.setEnabled(False)
5035            styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5036        else:
5037            self._view.ui.btn_pred_multi_next.setEnabled(True)
5038            tools.validate_protein_name(
5039                self._view.ui.txt_pred_multi_prot_name,
5040                self._view.ui.lbl_pred_multi_prot_name_status,
5041                self._view.ui.btn_pred_multi_next,
5042            )
5043
5044    def local_pred_multi_validate_protein_sequence(self) -> None:
5045        """Validates the input of the protein sequence in real-time."""
5046        tools.validate_protein_sequence(
5047            self._view.ui.txt_pred_multi_prot_seq,
5048            self._view.ui.lbl_pred_multi_prot_seq_status,
5049            self._view.ui.btn_pred_multi_prot_seq_add,
5050        )
5051
5052    def local_pred_multi_check_if_table_is_empty(self) -> None:
5053        """Checks if the table proteins to predict is empty."""
5054        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() == 0:
5055            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
5056            self._view.ui.btn_pred_multi_predict.setEnabled(False)
5057            gui_elements_to_show = [
5058                self._view.ui.lbl_pred_multi_prot_to_predict,
5059                self._view.ui.table_pred_multi_prot_to_predict,
5060                self._view.ui.btn_pred_multi_prot_to_predict_add,
5061            ]
5062            gui_elements_to_hide = [
5063                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5064                self._view.ui.lbl_pred_multi_prot_name_status,
5065                self._view.ui.btn_pred_multi_back,
5066                self._view.ui.btn_pred_multi_next,
5067                self._view.ui.lbl_pred_multi_prot_name,
5068                self._view.ui.txt_pred_multi_prot_name,
5069                self._view.ui.lbl_pred_multi_prot_seq,
5070                self._view.ui.txt_pred_multi_prot_seq,
5071                self._view.ui.lbl_pred_multi_prot_seq_status,
5072                self._view.ui.lbl_pred_multi_prot_seq_add,
5073                self._view.ui.btn_pred_multi_prot_seq_add,
5074                self._view.ui.lbl_pred_multi_prot_seq_overview,
5075                self._view.ui.list_pred_multi_prot_seq_overview,
5076                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5077                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5078                self._view.ui.btn_pred_multi_back_2,
5079                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5080                self._view.ui.lbl_pred_multi_advanced_config,
5081                self._view.ui.btn_pred_multi_advanced_config,
5082                self._view.ui.btn_pred_multi_predict,
5083            ]
5084            gui_utils.show_gui_elements(gui_elements_to_show)
5085            gui_utils.hide_gui_elements(gui_elements_to_hide)
5086            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5087        else:
5088            self._view.ui.btn_pred_multi_predict.setEnabled(True)
5089            gui_elements_to_show = [
5090                self._view.ui.lbl_pred_multi_prot_to_predict,
5091                self._view.ui.table_pred_multi_prot_to_predict,
5092                self._view.ui.btn_pred_multi_prot_to_predict_add,
5093                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5094                self._view.ui.lbl_pred_multi_advanced_config,
5095                self._view.ui.btn_pred_multi_advanced_config,
5096                self._view.ui.btn_pred_multi_predict,
5097            ]
5098            gui_elements_to_hide = [
5099                self._view.ui.lbl_pred_multi_prot_name_status,
5100                self._view.ui.btn_pred_multi_back,
5101                self._view.ui.btn_pred_multi_next,
5102                self._view.ui.lbl_pred_multi_prot_name,
5103                self._view.ui.txt_pred_multi_prot_name,
5104                self._view.ui.lbl_pred_multi_prot_seq,
5105                self._view.ui.txt_pred_multi_prot_seq,
5106                self._view.ui.lbl_pred_multi_prot_seq_status,
5107                self._view.ui.lbl_pred_multi_prot_seq_add,
5108                self._view.ui.btn_pred_multi_prot_seq_add,
5109                self._view.ui.lbl_pred_multi_prot_seq_overview,
5110                self._view.ui.list_pred_multi_prot_seq_overview,
5111                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5112                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5113                self._view.ui.btn_pred_multi_back_2,
5114                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5115            ]
5116            gui_utils.show_gui_elements(gui_elements_to_show)
5117            gui_utils.hide_gui_elements(gui_elements_to_hide)
5118            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5119
5120    def local_pred_multi_add_sequence_to_list(self) -> None:
5121        """Adds the entered sequence to the list of sequences of the protein."""
5122        self._view.ui.list_pred_multi_prot_seq_overview.addItem(
5123            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_multi_prot_seq.toPlainText()),
5124        )
5125        self.local_pred_multi_check_if_list_is_empty()
5126
5127    def local_pred_multi_remove_sequence_to_list(self) -> None:
5128        """Removes the entered sequence to the list of sequences of the protein."""
5129        self._view.ui.list_pred_multi_prot_seq_overview.takeItem(
5130            self._view.ui.list_pred_multi_prot_seq_overview.currentRow(),
5131        )
5132        self.local_pred_multi_check_if_list_is_empty()
5133        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)
5134
5135    def local_pred_multi_check_if_list_is_empty(self) -> None:
5136        """Checks if the list of sequences of the protein is empty."""
5137        if self._view.ui.list_pred_multi_prot_seq_overview.count() == 0:
5138            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5139        else:
5140            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(True)
5141
5142    def local_pred_multi_add(self) -> None:
5143        """Shows the gui elements for the protein name."""
5144        gui_elements_to_show = [
5145            self._view.ui.lbl_pred_multi_prot_to_predict,
5146            self._view.ui.table_pred_multi_prot_to_predict,
5147            self._view.ui.lbl_pred_multi_prot_name,
5148            self._view.ui.txt_pred_multi_prot_name,
5149            self._view.ui.lbl_pred_multi_prot_name_status,
5150            self._view.ui.btn_pred_multi_back,
5151            self._view.ui.btn_pred_multi_next,
5152        ]
5153        gui_elements_to_hide = [
5154            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5155            self._view.ui.btn_pred_multi_prot_to_predict_add,
5156            self._view.ui.lbl_pred_multi_prot_seq,
5157            self._view.ui.txt_pred_multi_prot_seq,
5158            self._view.ui.lbl_pred_multi_prot_seq_status,
5159            self._view.ui.lbl_pred_multi_prot_seq_add,
5160            self._view.ui.btn_pred_multi_prot_seq_add,
5161            self._view.ui.lbl_pred_multi_prot_seq_overview,
5162            self._view.ui.list_pred_multi_prot_seq_overview,
5163            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5164            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5165            self._view.ui.btn_pred_multi_back_2,
5166            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5167            self._view.ui.lbl_pred_multi_advanced_config,
5168            self._view.ui.btn_pred_multi_advanced_config,
5169            self._view.ui.btn_pred_multi_predict,
5170        ]
5171        gui_utils.show_gui_elements(gui_elements_to_show)
5172        gui_utils.hide_gui_elements(gui_elements_to_hide)
5173        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5174        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5175        self._view.ui.btn_pred_multi_next.setEnabled(False)
5176        self._view.ui.txt_pred_multi_prot_name.clear()
5177        styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5178        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5179            try:
5180                self._view.ui.table_pred_multi_prot_to_predict.currentItem().setSelected(False)
5181            except AttributeError:
5182                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")
5183
5184    def local_pred_multi_back(self) -> None:
5185        """Hides the gui elements for the protein name."""
5186        gui_elements_to_show = [
5187            self._view.ui.lbl_pred_multi_prot_to_predict,
5188            self._view.ui.table_pred_multi_prot_to_predict,
5189            self._view.ui.btn_pred_multi_prot_to_predict_add,
5190        ]
5191        gui_elements_to_hide = [
5192            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5193            self._view.ui.lbl_pred_multi_prot_name,
5194            self._view.ui.txt_pred_multi_prot_name,
5195            self._view.ui.lbl_pred_multi_prot_name_status,
5196            self._view.ui.btn_pred_multi_back,
5197            self._view.ui.btn_pred_multi_next,
5198            self._view.ui.lbl_pred_multi_prot_seq,
5199            self._view.ui.txt_pred_multi_prot_seq,
5200            self._view.ui.lbl_pred_multi_prot_seq_status,
5201            self._view.ui.lbl_pred_multi_prot_seq_add,
5202            self._view.ui.btn_pred_multi_prot_seq_add,
5203            self._view.ui.lbl_pred_multi_prot_seq_overview,
5204            self._view.ui.list_pred_multi_prot_seq_overview,
5205            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5206            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5207            self._view.ui.btn_pred_multi_back_2,
5208            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5209            self._view.ui.lbl_pred_multi_advanced_config,
5210            self._view.ui.btn_pred_multi_advanced_config,
5211            self._view.ui.btn_pred_multi_predict,
5212        ]
5213        gui_utils.show_gui_elements(gui_elements_to_show)
5214        gui_utils.hide_gui_elements(gui_elements_to_hide)
5215        self.local_pred_multi_check_if_table_is_empty()
5216
5217    def local_pred_multi_next(self) -> None:
5218        """Shows the gui elements for the protein sequence."""
5219        gui_elements_to_show = [
5220            self._view.ui.lbl_pred_multi_prot_to_predict,
5221            self._view.ui.table_pred_multi_prot_to_predict,
5222            self._view.ui.lbl_pred_multi_prot_name,
5223            self._view.ui.txt_pred_multi_prot_name,
5224            self._view.ui.lbl_pred_multi_prot_seq,
5225            self._view.ui.txt_pred_multi_prot_seq,
5226            self._view.ui.lbl_pred_multi_prot_seq_status,
5227            self._view.ui.lbl_pred_multi_prot_seq_add,
5228            self._view.ui.btn_pred_multi_prot_seq_add,
5229            self._view.ui.lbl_pred_multi_prot_seq_overview,
5230            self._view.ui.list_pred_multi_prot_seq_overview,
5231            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5232            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5233            self._view.ui.btn_pred_multi_back_2,
5234            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5235        ]
5236        gui_elements_to_hide = [
5237            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5238            self._view.ui.btn_pred_multi_prot_to_predict_add,
5239            self._view.ui.lbl_pred_multi_prot_name_status,
5240            self._view.ui.btn_pred_multi_back,
5241            self._view.ui.btn_pred_multi_next,
5242            self._view.ui.lbl_pred_multi_advanced_config,
5243            self._view.ui.btn_pred_multi_advanced_config,
5244            self._view.ui.btn_pred_multi_predict,
5245        ]
5246        gui_utils.show_gui_elements(gui_elements_to_show)
5247        gui_utils.hide_gui_elements(gui_elements_to_hide)
5248        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5249        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5250        self._view.ui.txt_pred_multi_prot_seq.clear()
5251        self._view.ui.list_pred_multi_prot_seq_overview.clear()
5252        self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5253        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)
5254        styles.color_button_not_ready(self._view.ui.btn_pred_multi_prot_to_predict_add_2)
5255
5256    def local_pred_multi_back_2(self) -> None:
5257        """Hides the gui elements for the protein sequence."""
5258        gui_elements_to_show = [
5259            self._view.ui.lbl_pred_multi_prot_to_predict,
5260            self._view.ui.table_pred_multi_prot_to_predict,
5261            self._view.ui.lbl_pred_multi_prot_name_status,
5262            self._view.ui.btn_pred_multi_back,
5263            self._view.ui.btn_pred_multi_next,
5264            self._view.ui.lbl_pred_multi_prot_name,
5265            self._view.ui.txt_pred_multi_prot_name,
5266        ]
5267        gui_elements_to_hide = [
5268            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5269            self._view.ui.btn_pred_multi_prot_to_predict_add,
5270            self._view.ui.lbl_pred_multi_prot_seq,
5271            self._view.ui.txt_pred_multi_prot_seq,
5272            self._view.ui.lbl_pred_multi_prot_seq_status,
5273            self._view.ui.lbl_pred_multi_prot_seq_add,
5274            self._view.ui.btn_pred_multi_prot_seq_add,
5275            self._view.ui.lbl_pred_multi_prot_seq_overview,
5276            self._view.ui.list_pred_multi_prot_seq_overview,
5277            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5278            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5279            self._view.ui.btn_pred_multi_back_2,
5280            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5281            self._view.ui.lbl_pred_multi_advanced_config,
5282            self._view.ui.btn_pred_multi_advanced_config,
5283            self._view.ui.btn_pred_multi_predict,
5284        ]
5285        gui_utils.show_gui_elements(gui_elements_to_show)
5286        gui_utils.hide_gui_elements(gui_elements_to_hide)
5287        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5288        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5289
5290    def local_pred_multi_prot_seq_overview_item_changed(self) -> None:
5291        """Enables the remove button of the list sequences of the protein."""
5292        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(True)
5293
5294    def local_pred_multi_prot_to_predict_item_changed(self) -> None:
5295        """Enables the remove button of the table proteins to predict."""
5296        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(True)
5297
5298    def local_pred_multi_prot_to_predict_add_2(self) -> None:
5299        """Adds the protein to the list of proteins to predict."""
5300        for i in range(self._view.ui.list_pred_multi_prot_seq_overview.count()):
5301            self._view.ui.table_pred_multi_prot_to_predict.setRowCount(
5302                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5303            )
5304            self._view.ui.table_pred_multi_prot_to_predict.insertRow(
5305                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5306            )
5307            tmp_chain_seq = (
5308                constants.chain_dict.get(i),
5309                self._view.ui.list_pred_multi_prot_seq_overview.item(i).text(),
5310            )
5311            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5312                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5313                0,
5314                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
5315            )
5316            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5317                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5318                1,
5319                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
5320            )
5321            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_multi_prot_name.text())
5322            self._view.ui.table_pred_multi_prot_to_predict.setVerticalHeaderItem(
5323                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5324                name_item,
5325            )
5326        self._view.ui.table_pred_multi_prot_to_predict.resizeColumnsToContents()
5327        self.local_pred_multi_check_if_table_is_empty()
5328        gui_elements_to_show = [
5329            self._view.ui.lbl_pred_multi_prot_to_predict,
5330            self._view.ui.table_pred_multi_prot_to_predict,
5331            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5332            self._view.ui.btn_pred_multi_prot_to_predict_add,
5333            self._view.ui.lbl_pred_multi_advanced_config,
5334            self._view.ui.btn_pred_multi_advanced_config,
5335            self._view.ui.btn_pred_multi_predict,
5336        ]
5337        gui_elements_to_hide = [
5338            self._view.ui.lbl_pred_multi_prot_name_status,
5339            self._view.ui.btn_pred_multi_back,
5340            self._view.ui.btn_pred_multi_next,
5341            self._view.ui.lbl_pred_multi_prot_name,
5342            self._view.ui.txt_pred_multi_prot_name,
5343            self._view.ui.lbl_pred_multi_prot_seq,
5344            self._view.ui.txt_pred_multi_prot_seq,
5345            self._view.ui.lbl_pred_multi_prot_seq_status,
5346            self._view.ui.lbl_pred_multi_prot_seq_add,
5347            self._view.ui.btn_pred_multi_prot_seq_add,
5348            self._view.ui.lbl_pred_multi_prot_seq_overview,
5349            self._view.ui.list_pred_multi_prot_seq_overview,
5350            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5351            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5352            self._view.ui.btn_pred_multi_back_2,
5353            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5354        ]
5355        gui_utils.show_gui_elements(gui_elements_to_show)
5356        gui_utils.hide_gui_elements(gui_elements_to_hide)
5357        self._init_local_pred_multi_page()
5358        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5359
5360    def local_pred_multi_remove(self) -> None:
5361        """Removes the selected protein from the list of proteins to predict."""
5362        self._view.ui.table_pred_multi_prot_to_predict.removeRow(
5363            self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5364        )
5365        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5366            prot_name = self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(
5367                self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5368            ).text()
5369            for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount()):
5370                if self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
5371                    self._view.ui.table_pred_multi_prot_to_predict.setItem(
5372                        i,
5373                        0,
5374                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
5375                    )
5376        self.local_pred_multi_check_if_table_is_empty()
5377        gui_elements_to_show = [
5378            self._view.ui.lbl_pred_multi_prot_to_predict,
5379            self._view.ui.table_pred_multi_prot_to_predict,
5380            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5381            self._view.ui.btn_pred_multi_prot_to_predict_add,
5382            self._view.ui.lbl_pred_multi_advanced_config,
5383            self._view.ui.btn_pred_multi_advanced_config,
5384            self._view.ui.btn_pred_multi_predict,
5385        ]
5386        gui_elements_to_hide = [
5387            self._view.ui.lbl_pred_multi_prot_name_status,
5388            self._view.ui.btn_pred_multi_back,
5389            self._view.ui.btn_pred_multi_next,
5390            self._view.ui.lbl_pred_multi_prot_name,
5391            self._view.ui.txt_pred_multi_prot_name,
5392            self._view.ui.lbl_pred_multi_prot_seq,
5393            self._view.ui.txt_pred_multi_prot_seq,
5394            self._view.ui.lbl_pred_multi_prot_seq_status,
5395            self._view.ui.lbl_pred_multi_prot_seq_add,
5396            self._view.ui.btn_pred_multi_prot_seq_add,
5397            self._view.ui.lbl_pred_multi_prot_seq_overview,
5398            self._view.ui.list_pred_multi_prot_seq_overview,
5399            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5400            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5401            self._view.ui.btn_pred_multi_back_2,
5402            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5403        ]
5404        gui_utils.show_gui_elements(gui_elements_to_show)
5405        gui_utils.hide_gui_elements(gui_elements_to_hide)
5406        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5407        self.local_pred_multi_check_if_table_is_empty()
5408
5409    # </editor-fold>
5410
5411    # <editor-fold desc="Monomer prediction + analysis">
5412    def _init_mono_pred_analysis_page(self) -> None:
5413        """Clears all text boxes and sets default values for the gui elements."""
5414        # <editor-fold desc="Prediction section">
5415        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5416        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5417        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
5418            self._view.ui.table_pred_analysis_mono_prot_to_predict.removeRow(i)
5419        # sets up defaults: Prediction
5420        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5421        self._view.ui.btn_pred_analysis_mono_add_protein.setEnabled(False)
5422        self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("")
5423        self._view.ui.lbl_pred_analysis_mono_seq_name_status.setText("")
5424
5425        # </editor-fold>
5426
5427        # <editor-fold desc="Analysis section">
5428        self._view.ui.list_pred_analysis_mono_overview.clear()
5429        self._view.ui.btn_pred_analysis_mono_remove.hide()
5430
5431        # </editor-fold>
5432
5433    def display_monomer_pred_analysis(self) -> None:
5434        """Displays the monomer prediction + analysis page."""
5435        # checks internet connection
5436        if not tools.check_internet_connectivity():
5437            gui_utils.no_internet_dialog()
5438            return
5439
5440        self._init_mono_pred_analysis_page()
5441        self._view.ui.table_pred_analysis_mono_prot_to_predict.clear()
5442        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5443            0,
5444            QtWidgets.QTableWidgetItem("Chain"),
5445        )
5446        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5447            1,
5448            QtWidgets.QTableWidgetItem("Sequence"),
5449        )
5450        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5451        gui_elements_to_show = [
5452            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5453            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5454            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5455        ]
5456        gui_elements_to_hide = [
5457            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5458            self._view.ui.lbl_pred_analysis_mono_prot_name,
5459            self._view.ui.txt_pred_analysis_mono_prot_name,
5460            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5461            self._view.ui.btn_pred_analysis_mono_back,
5462            self._view.ui.btn_pred_analysis_mono_next,
5463            self._view.ui.lbl_pred_analysis_mono_seq_name,
5464            self._view.ui.txt_pred_analysis_mono_seq_name,
5465            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5466            self._view.ui.btn_pred_analysis_mono_back_2,
5467            self._view.ui.btn_pred_analysis_mono_add_protein,
5468            self._view.ui.lbl_pred_mono_advanced_config_2,
5469            self._view.ui.btn_pred_mono_advanced_config_2,
5470            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5471            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5472        ]
5473        gui_utils.show_gui_elements(gui_elements_to_show)
5474        gui_utils.hide_gui_elements(gui_elements_to_hide)
5475        if self._view.ui.tabWidget.currentIndex() == 1:
5476            self._view.ui.tabWidget.setCurrentIndex(0)
5477        self._view.ui.tabWidget.setTabEnabled(1, False)
5478        self._view.ui.tabWidget.setTabEnabled(0, True)
5479        tools.switch_page(
5480            self._view.ui.stackedWidget,
5481            self._view.ui.lbl_page_title,
5482            21,
5483            "Monomer Prediction + Analysis",
5484        )
5485        self.last_sidebar_button = styles.color_sidebar_buttons(
5486            self.last_sidebar_button,
5487            self._view.ui.btn_pred_analysis_monomer_page,
5488        )
5489        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEnabled(True)
5490
5491    # <editor-fold desc="Sections">
5492
5493    # <editor-fold desc="Prediction section">
5494    def mono_pred_analysis_validate_protein_name(self) -> None:
5495        """Validates the input of the protein name in real-time."""
5496        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5497            self._view.ui.txt_pred_analysis_mono_prot_name.text(),
5498            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5499        ):
5500            self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("Protein name already used.")
5501            self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5502            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5503        else:
5504            self._view.ui.btn_pred_analysis_mono_next.setEnabled(True)
5505            tools.validate_protein_name(
5506                self._view.ui.txt_pred_analysis_mono_prot_name,
5507                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5508                self._view.ui.btn_pred_analysis_mono_next,
5509            )
5510
5511    def mono_pred_analysis_validate_protein_sequence(self) -> None:
5512        """Validates the input of the protein sequence in real-time."""
5513        tools.validate_protein_sequence(
5514            self._view.ui.txt_pred_analysis_mono_seq_name,
5515            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5516            self._view.ui.btn_pred_analysis_mono_add_protein,
5517        )
5518
5519    def mono_pred_analysis_check_if_table_is_empty(self) -> None:
5520        """Checks if the table proteins to predict is empty."""
5521        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() == 0:
5522            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_go_analysis_setup)
5523            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(False)
5524            gui_elements_to_show = [
5525                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5526                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5527                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5528            ]
5529            gui_elements_to_hide = [
5530                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5531                self._view.ui.lbl_pred_analysis_mono_prot_name,
5532                self._view.ui.txt_pred_analysis_mono_prot_name,
5533                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5534                self._view.ui.btn_pred_analysis_mono_back,
5535                self._view.ui.btn_pred_analysis_mono_next,
5536                self._view.ui.lbl_pred_analysis_mono_seq_name,
5537                self._view.ui.txt_pred_analysis_mono_seq_name,
5538                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5539                self._view.ui.btn_pred_analysis_mono_back_2,
5540                self._view.ui.btn_pred_analysis_mono_add_protein,
5541                self._view.ui.lbl_pred_mono_advanced_config_2,
5542                self._view.ui.btn_pred_mono_advanced_config_2,
5543                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5544                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5545            ]
5546            gui_utils.show_gui_elements(gui_elements_to_show)
5547            gui_utils.hide_gui_elements(gui_elements_to_hide)
5548        else:
5549            gui_elements_to_show = [
5550                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5551                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5552                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5553                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5554                self._view.ui.lbl_pred_mono_advanced_config_2,
5555                self._view.ui.btn_pred_mono_advanced_config_2,
5556                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5557                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5558            ]
5559            gui_elements_to_hide = [
5560                self._view.ui.lbl_pred_analysis_mono_prot_name,
5561                self._view.ui.txt_pred_analysis_mono_prot_name,
5562                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5563                self._view.ui.btn_pred_analysis_mono_back,
5564                self._view.ui.btn_pred_analysis_mono_next,
5565                self._view.ui.lbl_pred_analysis_mono_seq_name,
5566                self._view.ui.txt_pred_analysis_mono_seq_name,
5567                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5568                self._view.ui.btn_pred_analysis_mono_back_2,
5569                self._view.ui.btn_pred_analysis_mono_add_protein,
5570            ]
5571            gui_utils.show_gui_elements(gui_elements_to_show)
5572            gui_utils.hide_gui_elements(gui_elements_to_hide)
5573            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)
5574
5575    def setup_defaults_monomer_prediction_analysis(self) -> None:
5576        """Sets up default values for the prediction tab."""
5577        # clears everything
5578        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5579        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5580        # sets up defaults: Prediction
5581        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5582        self._view.ui.btn_pred_analysis_mono_add_protein.setEnabled(False)
5583        self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("")
5584        self._view.ui.lbl_pred_analysis_mono_seq_name_status.setText("")
5585
5586    def mono_pred_analysis_add_seq_to_predict(self) -> None:
5587        """Shows the gui elements for the protein name."""
5588        gui_elements_to_show = [
5589            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5590            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5591            self._view.ui.lbl_pred_analysis_mono_prot_name,
5592            self._view.ui.txt_pred_analysis_mono_prot_name,
5593            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5594            self._view.ui.btn_pred_analysis_mono_back,
5595            self._view.ui.btn_pred_analysis_mono_next,
5596        ]
5597        gui_utils.enable_text_box(
5598            self._view.ui.txt_pred_analysis_mono_prot_name,
5599            self._view.ui.lbl_pred_analysis_mono_prot_name,
5600        )
5601        gui_elements_to_hide = [
5602            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5603            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5604            self._view.ui.lbl_pred_analysis_mono_seq_name,
5605            self._view.ui.txt_pred_analysis_mono_seq_name,
5606            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5607            self._view.ui.btn_pred_analysis_mono_back_2,
5608            self._view.ui.btn_pred_analysis_mono_add_protein,
5609            self._view.ui.lbl_pred_mono_advanced_config_2,
5610            self._view.ui.btn_pred_mono_advanced_config_2,
5611            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5612            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5613        ]
5614        gui_utils.disable_text_box(
5615            self._view.ui.txt_pred_analysis_mono_seq_name,
5616            self._view.ui.lbl_pred_analysis_mono_seq_name,
5617        )
5618        gui_utils.show_gui_elements(gui_elements_to_show)
5619        gui_utils.hide_gui_elements(gui_elements_to_hide)
5620        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5621        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5622        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5623        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() > 0:
5624            try:
5625                self._view.ui.table_pred_analysis_mono_prot_to_predict.currentItem().setSelected(False)
5626            except AttributeError:
5627                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")
5628
5629    def mono_pred_analysis_back(self) -> None:
5630        """Hides the gui elements for the protein name."""
5631        gui_elements_to_show = [
5632            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5633            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5634            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5635            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5636        ]
5637        gui_elements_to_hide = [
5638            self._view.ui.lbl_pred_analysis_mono_prot_name,
5639            self._view.ui.txt_pred_analysis_mono_prot_name,
5640            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5641            self._view.ui.btn_pred_analysis_mono_back,
5642            self._view.ui.btn_pred_analysis_mono_next,
5643            self._view.ui.lbl_pred_analysis_mono_seq_name,
5644            self._view.ui.txt_pred_analysis_mono_seq_name,
5645            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5646            self._view.ui.btn_pred_analysis_mono_back_2,
5647            self._view.ui.btn_pred_analysis_mono_add_protein,
5648            self._view.ui.lbl_pred_mono_advanced_config_2,
5649            self._view.ui.btn_pred_mono_advanced_config_2,
5650            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5651            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5652        ]
5653        gui_utils.show_gui_elements(gui_elements_to_show)
5654        gui_utils.hide_gui_elements(gui_elements_to_hide)
5655        self.mono_pred_analysis_check_if_table_is_empty()
5656        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5657
5658    def mono_pred_analysis_next(self) -> None:
5659        """Shows the gui elements for the protein sequence."""
5660        gui_elements_to_show = [
5661            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5662            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5663            self._view.ui.lbl_pred_analysis_mono_prot_name,
5664            self._view.ui.txt_pred_analysis_mono_prot_name,
5665            self._view.ui.lbl_pred_analysis_mono_seq_name,
5666            self._view.ui.txt_pred_analysis_mono_seq_name,
5667            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5668            self._view.ui.btn_pred_analysis_mono_back_2,
5669            self._view.ui.btn_pred_analysis_mono_add_protein,
5670        ]
5671        gui_utils.enable_text_box(
5672            self._view.ui.txt_pred_analysis_mono_seq_name,
5673            self._view.ui.lbl_pred_analysis_mono_seq_name,
5674        )
5675        gui_elements_to_hide = [
5676            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5677            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5678            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5679            self._view.ui.btn_pred_analysis_mono_back,
5680            self._view.ui.btn_pred_analysis_mono_next,
5681            self._view.ui.lbl_pred_mono_advanced_config_2,
5682            self._view.ui.btn_pred_mono_advanced_config_2,
5683            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5684            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5685        ]
5686        gui_utils.disable_text_box(
5687            self._view.ui.txt_pred_analysis_mono_prot_name,
5688            self._view.ui.lbl_pred_analysis_mono_prot_name,
5689        )
5690        gui_utils.show_gui_elements(gui_elements_to_show)
5691        gui_utils.hide_gui_elements(gui_elements_to_hide)
5692        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5693
5694    def mono_pred_analysis_back_2(self) -> None:
5695        """Hides the gui elements for the protein sequence."""
5696        gui_elements_to_show = [
5697            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5698            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5699            self._view.ui.lbl_pred_analysis_mono_prot_name,
5700            self._view.ui.txt_pred_analysis_mono_prot_name,
5701            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5702            self._view.ui.btn_pred_analysis_mono_back,
5703            self._view.ui.btn_pred_analysis_mono_next,
5704        ]
5705        gui_elements_to_hide = [
5706            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5707            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5708            self._view.ui.lbl_pred_analysis_mono_seq_name,
5709            self._view.ui.txt_pred_analysis_mono_seq_name,
5710            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5711            self._view.ui.btn_pred_analysis_mono_back_2,
5712            self._view.ui.btn_pred_analysis_mono_add_protein,
5713            self._view.ui.lbl_pred_mono_advanced_config_2,
5714            self._view.ui.btn_pred_mono_advanced_config_2,
5715            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5716            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5717        ]
5718        gui_utils.enable_text_box(
5719            self._view.ui.txt_pred_analysis_mono_prot_name,
5720            self._view.ui.lbl_pred_analysis_mono_prot_name,
5721        )
5722        gui_utils.disable_text_box(
5723            self._view.ui.txt_pred_analysis_mono_seq_name,
5724            self._view.ui.lbl_pred_analysis_mono_seq_name,
5725        )
5726        gui_utils.show_gui_elements(gui_elements_to_show)
5727        gui_utils.hide_gui_elements(gui_elements_to_hide)
5728
5729    def mono_pred_analysis_add_protein(self) -> None:
5730        """Adds the protein to the list of proteins to predict."""
5731        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5732            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5733        )
5734        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5735            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5736        )
5737        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5738            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5739            0,
5740            QtWidgets.QTableWidgetItem("A"),
5741        )
5742        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5743            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5744            1,
5745            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5746        )
5747        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5748            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5749            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5750        )
5751        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5752        self.mono_pred_analysis_check_if_table_is_empty()
5753        gui_elements_to_show = [
5754            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5755            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5756            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5757            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5758            self._view.ui.lbl_pred_mono_advanced_config_2,
5759            self._view.ui.btn_pred_mono_advanced_config_2,
5760            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5761            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5762        ]
5763        gui_utils.enable_text_box(
5764            self._view.ui.txt_pred_analysis_mono_prot_name,
5765            self._view.ui.lbl_pred_analysis_mono_prot_name,
5766        )
5767        gui_elements_to_hide = [
5768            self._view.ui.lbl_pred_analysis_mono_prot_name,
5769            self._view.ui.txt_pred_analysis_mono_prot_name,
5770            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5771            self._view.ui.btn_pred_analysis_mono_back,
5772            self._view.ui.btn_pred_analysis_mono_next,
5773            self._view.ui.lbl_pred_analysis_mono_seq_name,
5774            self._view.ui.txt_pred_analysis_mono_seq_name,
5775            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5776            self._view.ui.btn_pred_analysis_mono_back_2,
5777            self._view.ui.btn_pred_analysis_mono_add_protein,
5778        ]
5779        gui_utils.show_gui_elements(gui_elements_to_show)
5780        gui_utils.hide_gui_elements(gui_elements_to_hide)
5781        self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)
5782        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5783        self.setup_defaults_monomer_prediction()
5784
5785    def mono_pred_analysis_prediction_overview_item_clicked(self) -> None:
5786        """Enables the remove button."""
5787        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(True)
5788
5789    def mono_pred_analysis_add_protein_to_predict(self) -> None:
5790        """Needs to be removed."""
5791        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5792            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5793        )
5794        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5795            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5796        )
5797        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5798            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5799            0,
5800            QtWidgets.QTableWidgetItem("A"),
5801        )
5802        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5803            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5804            1,
5805            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5806        )
5807        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5808            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5809            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5810        )
5811        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5812        self.mono_pred_analysis_check_if_table_is_empty()
5813        self.setup_defaults_monomer_prediction_analysis()
5814
5815    def mono_pred_analysis_remove_protein_to_predict(self) -> None:
5816        """Removes the selected protein from the list of proteins to predict."""
5817        self._view.ui.table_pred_analysis_mono_prot_to_predict.removeRow(
5818            self._view.ui.table_pred_analysis_mono_prot_to_predict.currentRow(),
5819        )
5820        self.mono_pred_analysis_check_if_table_is_empty()
5821        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5822
5823    # </editor-fold>
5824
5825    # <editor-fold desc="Analysis section">
5826    def mono_pred_analysis_structure_analysis_add(self) -> None:
5827        """Shows the gui elements for the selection of the two proteins."""
5828        gui_elements_to_show = [
5829            self._view.ui.lbl_pred_analysis_mono_overview,
5830            self._view.ui.list_pred_analysis_mono_overview,
5831            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5832            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5833            self._view.ui.lbl_analysis_batch_vs_2,
5834            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5835            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5836            self._view.ui.btn_pred_analysis_mono_back_3,
5837            self._view.ui.btn_pred_analysis_mono_next_2,
5838        ]
5839        gui_elements_to_hide = [
5840            self._view.ui.btn_pred_analysis_mono_remove,
5841            self._view.ui.btn_pred_analysis_mono_add,
5842            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5843            self._view.ui.list_pred_analysis_mono_ref_chains,
5844            self._view.ui.btn_pred_analysis_mono_back_4,
5845            self._view.ui.btn_pred_analysis_mono_next_3,
5846            self._view.ui.lbl_pred_analysis_mono_model_chains,
5847            self._view.ui.list_pred_analysis_mono_model_chains,
5848            self._view.ui.btn_pred_analysis_mono_back_5,
5849            self._view.ui.btn_pred_analysis_mono_next_4,
5850            self._view.ui.lbl_pred_analysis_mono_images,
5851            self._view.ui.cb_pred_analysis_mono_images,
5852            self._view.ui.btn_pred_analysis_mono_start,
5853            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5854        ]
5855        gui_utils.show_gui_elements(gui_elements_to_show)
5856        gui_utils.hide_gui_elements(gui_elements_to_hide)
5857        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.clear()
5858        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.clear()
5859        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5860        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")
5861        self.fill_mono_pred_analysis_protein_boxes()
5862        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5863            try:
5864                self._view.ui.list_pred_analysis_mono_overview.currentItem().setSelected(False)
5865            except AttributeError:
5866                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
5867
5868    def mono_pred_analysis_structure_analysis_back_3(self) -> None:
5869        """Hides the gui elements to select the two proteins."""
5870        gui_elements_to_show = [
5871            self._view.ui.lbl_pred_analysis_mono_overview,
5872            self._view.ui.list_pred_analysis_mono_overview,
5873            self._view.ui.btn_pred_analysis_mono_add,
5874            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5875        ]
5876        gui_elements_to_hide = [
5877            self._view.ui.btn_pred_analysis_mono_remove,
5878            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5879            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5880            self._view.ui.lbl_analysis_batch_vs_2,
5881            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5882            self._view.ui.list_pred_analysis_mono_ref_chains,
5883            self._view.ui.btn_pred_analysis_mono_back_4,
5884            self._view.ui.btn_pred_analysis_mono_next_3,
5885            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5886            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5887            self._view.ui.btn_pred_analysis_mono_back_3,
5888            self._view.ui.btn_pred_analysis_mono_next_2,
5889            self._view.ui.lbl_pred_analysis_mono_model_chains,
5890            self._view.ui.list_pred_analysis_mono_model_chains,
5891            self._view.ui.btn_pred_analysis_mono_back_5,
5892            self._view.ui.btn_pred_analysis_mono_next_4,
5893            self._view.ui.lbl_pred_analysis_mono_images,
5894            self._view.ui.cb_pred_analysis_mono_images,
5895            self._view.ui.btn_pred_analysis_mono_start,
5896        ]
5897        gui_utils.show_gui_elements(gui_elements_to_show)
5898        gui_utils.hide_gui_elements(gui_elements_to_hide)
5899        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5900            self._view.ui.btn_pred_analysis_mono_remove.show()
5901            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
5902            self._view.ui.btn_pred_analysis_mono_start.show()
5903            self._view.ui.lbl_pred_analysis_mono_images.show()
5904            self._view.ui.cb_pred_analysis_mono_images.show()
5905
5906    def mono_pred_analysis_structure_analysis_next_3(self) -> None:
5907        """Shows the gui elements to select the chains of protein 2."""
5908        gui_elements_to_show = [
5909            self._view.ui.lbl_pred_analysis_mono_overview,
5910            self._view.ui.list_pred_analysis_mono_overview,
5911            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5912            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5913            self._view.ui.lbl_analysis_batch_vs_2,
5914            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5915            self._view.ui.list_pred_analysis_mono_ref_chains,
5916            self._view.ui.lbl_pred_analysis_mono_model_chains,
5917            self._view.ui.list_pred_analysis_mono_model_chains,
5918            self._view.ui.btn_pred_analysis_mono_back_5,
5919            self._view.ui.btn_pred_analysis_mono_next_4,
5920        ]
5921        gui_elements_to_hide = [
5922            self._view.ui.btn_pred_analysis_mono_remove,
5923            self._view.ui.btn_pred_analysis_mono_add,
5924            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5925            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5926            self._view.ui.btn_pred_analysis_mono_back_3,
5927            self._view.ui.btn_pred_analysis_mono_next_2,
5928            self._view.ui.btn_pred_analysis_mono_back_4,
5929            self._view.ui.btn_pred_analysis_mono_next_3,
5930            self._view.ui.lbl_pred_analysis_mono_images,
5931            self._view.ui.cb_pred_analysis_mono_images,
5932            self._view.ui.btn_pred_analysis_mono_start,
5933            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5934        ]
5935        gui_utils.show_gui_elements(gui_elements_to_show)
5936        gui_utils.hide_gui_elements(gui_elements_to_hide)
5937        self._view.ui.list_pred_analysis_mono_model_chains.clear()
5938        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(False)
5939        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
5940
5941        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
5942            if (
5943                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text()
5944                == self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText()
5945            ):
5946                self._view.ui.list_pred_analysis_mono_model_chains.addItem(
5947                    self._view.ui.table_pred_analysis_mono_prot_to_predict.item(i, 0).text(),
5948                )
5949        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 0:
5950            tmp_protein = self._current_project.search_protein(
5951                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
5952            )
5953            for tmp_chain in tmp_protein.chains:
5954                if tmp_chain.chain_type == "protein_chain":
5955                    self._view.ui.list_pred_analysis_mono_model_chains.addItem(tmp_chain.chain_letter)
5956        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 1:
5957            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5958                f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5959            )
5960        else:
5961            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5962                f"Select {len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems())} chains "
5963                f"in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5964            )
5965
5966    def mono_pred_analysis_structure_analysis_back_4(self) -> None:
5967        """Hides the gui elements to select the chains in protein 1."""
5968        gui_elements_to_show = [
5969            self._view.ui.lbl_pred_analysis_mono_overview,
5970            self._view.ui.list_pred_analysis_mono_overview,
5971            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5972            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5973            self._view.ui.lbl_analysis_batch_vs_2,
5974            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5975            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5976            self._view.ui.btn_pred_analysis_mono_back_3,
5977            self._view.ui.btn_pred_analysis_mono_next_2,
5978            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5979        ]
5980        gui_elements_to_hide = [
5981            self._view.ui.btn_pred_analysis_mono_remove,
5982            self._view.ui.btn_pred_analysis_mono_add,
5983            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5984            self._view.ui.list_pred_analysis_mono_ref_chains,
5985            self._view.ui.btn_pred_analysis_mono_back_4,
5986            self._view.ui.btn_pred_analysis_mono_next_3,
5987            self._view.ui.lbl_pred_analysis_mono_model_chains,
5988            self._view.ui.list_pred_analysis_mono_model_chains,
5989            self._view.ui.btn_pred_analysis_mono_back_5,
5990            self._view.ui.btn_pred_analysis_mono_next_4,
5991            self._view.ui.lbl_pred_analysis_mono_images,
5992            self._view.ui.cb_pred_analysis_mono_images,
5993            self._view.ui.btn_pred_analysis_mono_start,
5994        ]
5995        gui_utils.show_gui_elements(gui_elements_to_show)
5996        gui_utils.hide_gui_elements(gui_elements_to_hide)
5997        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5998        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")
5999
6000    def mono_pred_analysis_structure_analysis_next_4(self) -> None:
6001        """Adds the protein pair to the list of protein pairs to analyze."""
6002        gui_elements_to_show = [
6003            self._view.ui.btn_pred_analysis_mono_remove,
6004            self._view.ui.btn_pred_analysis_mono_add,
6005            self._view.ui.lbl_pred_analysis_mono_overview,
6006            self._view.ui.list_pred_analysis_mono_overview,
6007            self._view.ui.lbl_pred_analysis_mono_images,
6008            self._view.ui.cb_pred_analysis_mono_images,
6009            self._view.ui.btn_pred_analysis_mono_start,
6010            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6011        ]
6012        gui_elements_to_hide = [
6013            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6014            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6015            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6016            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6017            self._view.ui.lbl_analysis_batch_vs_2,
6018            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6019            self._view.ui.list_pred_analysis_mono_ref_chains,
6020            self._view.ui.lbl_pred_analysis_mono_model_chains,
6021            self._view.ui.list_pred_analysis_mono_model_chains,
6022            self._view.ui.btn_pred_analysis_mono_back_3,
6023            self._view.ui.btn_pred_analysis_mono_next_2,
6024            self._view.ui.btn_pred_analysis_mono_back_4,
6025            self._view.ui.btn_pred_analysis_mono_next_3,
6026            self._view.ui.btn_pred_analysis_mono_back_5,
6027            self._view.ui.btn_pred_analysis_mono_next_4,
6028        ]
6029        gui_utils.show_gui_elements(gui_elements_to_show)
6030        gui_utils.hide_gui_elements(gui_elements_to_hide)
6031        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6032        prot_1_chains = []
6033        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6034            prot_1_chains.append(chain.text())
6035        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6036        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6037        prot_2_chains = []
6038        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6039            prot_2_chains.append(chain.text())
6040        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6041        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6042        item = QtWidgets.QListWidgetItem(analysis_name)
6043        self._view.ui.list_pred_analysis_mono_overview.addItem(item)
6044        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6045
6046    def mono_pred_analysis_structure_analysis_back_5(self) -> None:
6047        """Hides the gui elements to select the chains in protein 2."""
6048        gui_elements_to_show = [
6049            self._view.ui.lbl_pred_analysis_mono_overview,
6050            self._view.ui.list_pred_analysis_mono_overview,
6051            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6052            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6053            self._view.ui.lbl_analysis_batch_vs_2,
6054            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6055            self._view.ui.list_pred_analysis_mono_ref_chains,
6056            self._view.ui.btn_pred_analysis_mono_back_4,
6057            self._view.ui.btn_pred_analysis_mono_next_3,
6058        ]
6059        gui_elements_to_hide = [
6060            self._view.ui.btn_pred_analysis_mono_remove,
6061            self._view.ui.btn_pred_analysis_mono_add,
6062            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6063            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6064            self._view.ui.btn_pred_analysis_mono_back_3,
6065            self._view.ui.btn_pred_analysis_mono_next_2,
6066            self._view.ui.btn_pred_analysis_mono_back_5,
6067            self._view.ui.btn_pred_analysis_mono_next_4,
6068            self._view.ui.lbl_pred_analysis_mono_images,
6069            self._view.ui.cb_pred_analysis_mono_images,
6070            self._view.ui.btn_pred_analysis_mono_start,
6071            self._view.ui.lbl_pred_analysis_mono_model_chains,
6072            self._view.ui.list_pred_analysis_mono_model_chains,
6073            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6074        ]
6075        gui_utils.show_gui_elements(gui_elements_to_show)
6076        gui_utils.hide_gui_elements(gui_elements_to_hide)
6077        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(True)
6078
6079        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText())
6080        # for tmp_chain in tmp_protein.chains:
6081        #     if tmp_chain.chain_type == "protein_chain":
6082        #         self._view.ui.list_pred_analysis_mono_ref_chains.addItem(tmp_chain.chain_letter)
6083
6084    def mono_pred_analysis_structure_analysis_overview_clicked(self) -> None:
6085        """Enables the remove button."""
6086        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(True)
6087
6088    def fill_mono_pred_analysis_protein_boxes(self) -> None:
6089        """Fills the combo box of the protein structures."""
6090        protein_names = []
6091        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
6092            protein_names.append(self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text())
6093        for tmp_protein in self._current_project.proteins:
6094            protein_names.append(tmp_protein.get_molecule_object())
6095        protein_names.insert(0, "")
6096        self._view.ui.box_pred_analysis_mono_prot_struct_1.clear()
6097        self._view.ui.box_pred_analysis_mono_prot_struct_2.clear()
6098        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_1, protein_names)
6099        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_2, protein_names)
6100
6101    def remove_mono_pred_analysis_analysis_run(self) -> None:
6102        """Removes a selected protein pair form the list of protein pairs to analyze."""
6103        self._view.ui.list_pred_analysis_mono_overview.takeItem(
6104            self._view.ui.list_pred_analysis_mono_overview.currentRow(),
6105        )
6106        gui_elements_to_show = [
6107            self._view.ui.lbl_pred_analysis_mono_overview,
6108            self._view.ui.list_pred_analysis_mono_overview,
6109            self._view.ui.btn_pred_analysis_mono_add,
6110            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6111        ]
6112        gui_elements_to_hide = [
6113            self._view.ui.btn_pred_analysis_mono_remove,
6114            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6115            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6116            self._view.ui.lbl_analysis_batch_vs_2,
6117            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6118            self._view.ui.list_pred_analysis_mono_ref_chains,
6119            self._view.ui.btn_pred_analysis_mono_back_4,
6120            self._view.ui.btn_pred_analysis_mono_next_3,
6121            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6122            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6123            self._view.ui.btn_pred_analysis_mono_back_3,
6124            self._view.ui.btn_pred_analysis_mono_next_2,
6125            self._view.ui.lbl_pred_analysis_mono_model_chains,
6126            self._view.ui.list_pred_analysis_mono_model_chains,
6127            self._view.ui.btn_pred_analysis_mono_back_5,
6128            self._view.ui.btn_pred_analysis_mono_next_4,
6129            self._view.ui.lbl_pred_analysis_mono_images,
6130            self._view.ui.cb_pred_analysis_mono_images,
6131            self._view.ui.btn_pred_analysis_mono_start,
6132        ]
6133        gui_utils.show_gui_elements(gui_elements_to_show)
6134        gui_utils.hide_gui_elements(gui_elements_to_hide)
6135        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6136            self._view.ui.btn_pred_analysis_mono_remove.show()
6137            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6138            self._view.ui.btn_pred_analysis_mono_start.show()
6139            self._view.ui.lbl_pred_analysis_mono_images.show()
6140            self._view.ui.cb_pred_analysis_mono_images.show()
6141        # if self._view.ui.list_pred_analysis_mono_overview.count() == 0:
6142        #
6143        #     self._view.ui.btn_pred_analysis_mono_back_pred_setup.show()
6144        #     self._view.ui.btn_pred_analysis_mono_remove.hide()
6145
6146    def check_mono_pred_analysis_if_same_no_of_chains_selected(self) -> None:
6147        """Checks if the same number of chains were selected."""
6148        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6149        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems()):
6150            self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(True)
6151
6152        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6153        prot_1_chains = []
6154        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6155            prot_1_chains.append(chain.text())
6156        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6157        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6158        prot_2_chains = []
6159        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6160            prot_2_chains.append(chain.text())
6161        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6162        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6163        for tmp_row in range(self._view.ui.list_pred_analysis_mono_overview.count()):
6164            if analysis_name == self._view.ui.list_pred_analysis_mono_overview.item(tmp_row).text():
6165                self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6166                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next_4)
6167                return
6168
6169    def check_mono_pred_analysis_if_prot_structs_are_filled(self) -> None:
6170        """Checks if two proteins were selected."""
6171        prot_1 = self._view.ui.box_pred_analysis_mono_prot_struct_1.itemText(
6172            self._view.ui.box_pred_analysis_mono_prot_struct_1.currentIndex(),
6173        )
6174        prot_2 = self._view.ui.box_pred_analysis_mono_prot_struct_2.itemText(
6175            self._view.ui.box_pred_analysis_mono_prot_struct_2.currentIndex(),
6176        )
6177        if prot_1 != "" and prot_2 != "":
6178            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(True)
6179        else:
6180            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(False)
6181
6182    def count_mono_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
6183        """Counts the number of chains selected in protein 1."""
6184        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems())
6185        if self.no_of_selected_chains > 0:
6186            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(True)
6187        else:
6188            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(False)
6189
6190    # </editor-fold>
6191
6192    # </editor-fold>
6193
6194    def switch_monomer_pred_analysis_tab(self) -> None:
6195        """Switches the tabs from prediction to analysis and vice versa."""
6196        if self._view.ui.tabWidget.currentIndex() == 0:
6197            # goes from prediction to analysis
6198            self._view.ui.tabWidget.setTabEnabled(1, True)
6199            self._view.ui.tabWidget.setTabEnabled(0, False)
6200            self._view.ui.tabWidget.setCurrentIndex(1)
6201            gui_elements_to_show = [
6202                self._view.ui.lbl_pred_analysis_mono_overview,
6203                self._view.ui.list_pred_analysis_mono_overview,
6204                self._view.ui.btn_pred_analysis_mono_add,
6205                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6206            ]
6207            gui_elements_to_hide = [
6208                self._view.ui.btn_pred_analysis_mono_remove,
6209                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6210                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6211                self._view.ui.lbl_analysis_batch_vs_2,
6212                self._view.ui.lbl_pred_analysis_mono_ref_chains,
6213                self._view.ui.list_pred_analysis_mono_ref_chains,
6214                self._view.ui.btn_pred_analysis_mono_back_4,
6215                self._view.ui.btn_pred_analysis_mono_next_3,
6216                self._view.ui.box_pred_analysis_mono_prot_struct_1,
6217                self._view.ui.box_pred_analysis_mono_prot_struct_2,
6218                self._view.ui.btn_pred_analysis_mono_back_3,
6219                self._view.ui.btn_pred_analysis_mono_next_2,
6220                self._view.ui.lbl_pred_analysis_mono_model_chains,
6221                self._view.ui.list_pred_analysis_mono_model_chains,
6222                self._view.ui.btn_pred_analysis_mono_back_5,
6223                self._view.ui.btn_pred_analysis_mono_next_4,
6224                self._view.ui.lbl_pred_analysis_mono_images,
6225                self._view.ui.cb_pred_analysis_mono_images,
6226                self._view.ui.btn_pred_analysis_mono_start,
6227            ]
6228            gui_utils.show_gui_elements(gui_elements_to_show)
6229            gui_utils.hide_gui_elements(gui_elements_to_hide)
6230            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6231                self._view.ui.btn_pred_analysis_mono_remove.show()
6232                self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6233                self._view.ui.btn_pred_analysis_mono_start.show()
6234                self._view.ui.lbl_pred_analysis_mono_images.show()
6235                self._view.ui.cb_pred_analysis_mono_images.show()
6236        else:
6237            # goes from analysis to prediction
6238            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6239                gui_elements_to_show = [
6240                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6241                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6242                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6243                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6244                ]
6245                gui_elements_to_hide = [
6246                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6247                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6248                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6249                    self._view.ui.txt_pred_analysis_mono_prot_name,
6250                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6251                    self._view.ui.btn_pred_analysis_mono_back,
6252                    self._view.ui.btn_pred_analysis_mono_next,
6253                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6254                    self._view.ui.txt_pred_analysis_mono_seq_name,
6255                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6256                    self._view.ui.btn_pred_analysis_mono_back_2,
6257                    self._view.ui.btn_pred_analysis_mono_add_protein,
6258                    self._view.ui.lbl_pred_mono_advanced_config_2,
6259                    self._view.ui.btn_pred_mono_advanced_config_2,
6260                ]
6261                gui_utils.show_gui_elements(gui_elements_to_show)
6262                gui_utils.hide_gui_elements(gui_elements_to_hide)
6263            else:
6264                gui_elements_to_show = [
6265                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6266                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6267                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6268                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6269                    self._view.ui.lbl_pred_mono_advanced_config_2,
6270                    self._view.ui.btn_pred_mono_advanced_config_2,
6271                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6272                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6273                ]
6274                gui_elements_to_hide = [
6275                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6276                    self._view.ui.txt_pred_analysis_mono_prot_name,
6277                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6278                    self._view.ui.btn_pred_analysis_mono_back,
6279                    self._view.ui.btn_pred_analysis_mono_next,
6280                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6281                    self._view.ui.txt_pred_analysis_mono_seq_name,
6282                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6283                    self._view.ui.btn_pred_analysis_mono_back_2,
6284                    self._view.ui.btn_pred_analysis_mono_add_protein,
6285                ]
6286                gui_utils.show_gui_elements(gui_elements_to_show)
6287                gui_utils.hide_gui_elements(gui_elements_to_hide)
6288                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
6289            self._view.ui.tabWidget.setTabEnabled(0, True)
6290            self._view.ui.tabWidget.setTabEnabled(1, False)
6291            self._view.ui.tabWidget.setCurrentIndex(0)
6292
6293    # </editor-fold>
6294
6295    # <editor-fold desc="Multimer prediction + analysis">
6296    def _init_multi_pred_analysis_page(self) -> None:
6297        """Clears the text boxes and sets the default values for the gui elements."""
6298        # <editor-fold desc="Prediction section">
6299        # clears everything
6300        self._view.ui.txt_pred_analysis_multi_prot_name.clear()
6301        self._view.ui.txt_pred_analysis_multi_prot_seq.clear()
6302        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clear()
6303        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1, -1, -1):
6304            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(i)
6305
6306        # sets up defaults: Prediction
6307        self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6308        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6309        self._view.ui.lbl_pred_analysis_multi_prot_name_status.setText("")
6310        self._view.ui.lbl_pred_analysis_multi_prot_seq_status.setText("")
6311
6312        # </editor-fold>
6313
6314        # <editor-fold desc="Analysis section">
6315        self._view.ui.list_pred_analysis_multi_overview.clear()
6316        self._view.ui.btn_pred_analysis_multi_remove.hide()
6317
6318        # </editor-fold>
6319
6320        # self.multi_pred_analysis_show_protein_overview()
6321
6322    def display_multimer_pred_analysis(self) -> None:
6323        """Displays the multimer prediction + analysis page."""
6324        # checks internet connection
6325        if not tools.check_internet_connectivity():
6326            gui_utils.no_internet_dialog()
6327            return
6328
6329        self._init_multi_pred_analysis_page()
6330        self._view.ui.table_pred_analysis_multi_prot_to_predict.clear()
6331        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6332            0,
6333            QtWidgets.QTableWidgetItem("Chain"),
6334        )
6335        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6336            1,
6337            QtWidgets.QTableWidgetItem("Sequence"),
6338        )
6339        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6340        gui_elements_to_show = [
6341            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6342            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6343            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6344        ]
6345        gui_elements_to_hide = [
6346            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6347            self._view.ui.lbl_pred_analysis_multi_prot_name,
6348            self._view.ui.txt_pred_analysis_multi_prot_name,
6349            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6350            self._view.ui.btn_pred_analysis_multi_back,
6351            self._view.ui.btn_pred_analysis_multi_next,
6352            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6353            self._view.ui.txt_pred_analysis_multi_prot_seq,
6354            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6355            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6356            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6357            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6358            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6359            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6360            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6361            self._view.ui.btn_pred_analysis_multi_back_2,
6362            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6363            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6364            self._view.ui.btn_pred_analysis_multi_advanced_config,
6365            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6366            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6367        ]
6368        gui_utils.show_gui_elements(gui_elements_to_show)
6369        gui_utils.hide_gui_elements(gui_elements_to_hide)
6370        if self._view.ui.tabWidget_2.currentIndex() == 1:
6371            self._view.ui.tabWidget_2.setCurrentIndex(0)
6372        self._view.ui.tabWidget_2.setTabEnabled(1, False)
6373        self._view.ui.tabWidget_2.setTabEnabled(0, True)
6374        tools.switch_page(
6375            self._view.ui.stackedWidget,
6376            self._view.ui.lbl_page_title,
6377            22,
6378            "Multimer Prediction + Analysis",
6379        )
6380        self.last_sidebar_button = styles.color_sidebar_buttons(
6381            self.last_sidebar_button,
6382            self._view.ui.btn_pred_analysis_multimer_page,
6383        )
6384        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEnabled(True)
6385
6386    # <editor-fold desc="Prediction section">
6387    def multi_pred_analysis_validate_protein_name(self) -> None:
6388        """Validates the input of the protein name in real-time."""
6389        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
6390            self._view.ui.txt_pred_analysis_multi_prot_name.text(),
6391            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6392        ):
6393            self._view.ui.lbl_pred_analysis_multi_prot_name_status.setText("Protein name already used.")
6394            self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6395            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6396        else:
6397            self._view.ui.btn_pred_analysis_multi_next.setEnabled(True)
6398            tools.validate_protein_name(
6399                self._view.ui.txt_pred_analysis_multi_prot_name,
6400                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6401                self._view.ui.btn_pred_analysis_multi_next,
6402            )
6403
6404    def multi_pred_analysis_validate_protein_sequence(self) -> None:
6405        """Validates the input of the protein sequence in real-time."""
6406        tools.validate_protein_sequence(
6407            self._view.ui.txt_pred_analysis_multi_prot_seq,
6408            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6409            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6410        )
6411
6412    def multi_pred_analysis_check_if_list_is_empty(self) -> None:
6413        """Checks if the list of sequences of the protein is empty."""
6414        if self._view.ui.list_pred_analysis_multi_prot_seq_overview.count() == 0:
6415            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6416        else:
6417            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(True)
6418
6419    def multi_pred_analysis_add_sequence_to_list(self) -> None:
6420        """Adds the entered sequence to the sequences of the protein."""
6421        self._view.ui.list_pred_analysis_multi_prot_seq_overview.addItem(
6422            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_seq.toPlainText()),
6423        )
6424        self.multi_pred_analysis_check_if_list_is_empty()
6425
6426    def multi_pred_analysis_remove_sequence_to_list(self) -> None:
6427        """Removes the entered sequence from the sequences of the protein."""
6428        self._view.ui.list_pred_analysis_multi_prot_seq_overview.takeItem(
6429            self._view.ui.list_pred_analysis_multi_prot_seq_overview.currentRow(),
6430        )
6431        self.multi_pred_analysis_check_if_list_is_empty()
6432        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)
6433
6434    def multi_pred_analysis_check_if_table_is_empty(self) -> None:
6435        """Checks if the list of proteins to predict is empty."""
6436        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 0:
6437            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
6438            gui_elements_to_show = [
6439                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6440                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6441                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6442            ]
6443            gui_elements_to_hide = [
6444                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6445                self._view.ui.lbl_pred_analysis_multi_prot_name,
6446                self._view.ui.txt_pred_analysis_multi_prot_name,
6447                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6448                self._view.ui.btn_pred_analysis_multi_back,
6449                self._view.ui.btn_pred_analysis_multi_next,
6450                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6451                self._view.ui.txt_pred_analysis_multi_prot_seq,
6452                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6453                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6454                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6455                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6456                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6457                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6458                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6459                self._view.ui.btn_pred_analysis_multi_back_2,
6460                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6461                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6462                self._view.ui.btn_pred_analysis_multi_advanced_config,
6463                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6464                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6465            ]
6466            gui_utils.show_gui_elements(gui_elements_to_show)
6467            gui_utils.hide_gui_elements(gui_elements_to_hide)
6468            self._view.ui.btn_pred_multi_predict.setEnabled(False)
6469            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
6470        else:
6471            self._view.ui.btn_pred_multi_predict.setEnabled(True)
6472            gui_elements_to_show = [
6473                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6474                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6475                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6476                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6477                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6478                self._view.ui.btn_pred_analysis_multi_advanced_config,
6479                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6480                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6481            ]
6482            gui_elements_to_hide = [
6483                self._view.ui.lbl_pred_analysis_multi_prot_name,
6484                self._view.ui.txt_pred_analysis_multi_prot_name,
6485                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6486                self._view.ui.btn_pred_analysis_multi_back,
6487                self._view.ui.btn_pred_analysis_multi_next,
6488                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6489                self._view.ui.txt_pred_analysis_multi_prot_seq,
6490                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6491                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6492                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6493                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6494                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6495                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6496                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6497                self._view.ui.btn_pred_analysis_multi_back_2,
6498                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6499            ]
6500            gui_utils.show_gui_elements(gui_elements_to_show)
6501            gui_utils.hide_gui_elements(gui_elements_to_hide)
6502            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
6503
6504    def multi_pred_analysis_add_protein_to_predict(self) -> None:
6505        """Adds the proteins to the list of proteins to predict."""
6506        for i in range(self._view.ui.list_pred_analysis_multi_prot_seq_overview.count()):
6507            self._view.ui.table_pred_analysis_multi_prot_to_predict.setRowCount(
6508                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6509            )
6510            self._view.ui.table_pred_analysis_multi_prot_to_predict.insertRow(
6511                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6512            )
6513            tmp_chain_seq = (
6514                constants.chain_dict.get(i),
6515                self._view.ui.list_pred_analysis_multi_prot_seq_overview.item(i).text(),
6516            )
6517            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6518                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6519                0,
6520                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
6521            )
6522            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6523                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6524                1,
6525                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
6526            )
6527            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_name.text())
6528            self._view.ui.table_pred_analysis_multi_prot_to_predict.setVerticalHeaderItem(
6529                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6530                name_item,
6531            )
6532        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6533        self.multi_pred_analysis_check_if_table_is_empty()
6534        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)
6535
6536    def multi_pred_analysis_remove_protein_to_predict(self) -> None:
6537        """Removes the selected protein from the list of proteins to predict."""
6538        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 1:
6539            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(0)
6540        else:
6541            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(
6542                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6543            )
6544            prot_name = self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(
6545                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6546            ).text()
6547            for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6548                if self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
6549                    self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6550                        i,
6551                        0,
6552                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
6553                    )
6554        self.multi_pred_analysis_check_if_table_is_empty()
6555        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)
6556
6557    def multi_pred_analysis_add(self) -> None:
6558        """Shows the gui elements for the protein name."""
6559        gui_elements_to_show = [
6560            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6561            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6562            self._view.ui.lbl_pred_analysis_multi_prot_name,
6563            self._view.ui.txt_pred_analysis_multi_prot_name,
6564            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6565            self._view.ui.btn_pred_analysis_multi_back,
6566            self._view.ui.btn_pred_analysis_multi_next,
6567        ]
6568        gui_elements_to_hide = [
6569            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6570            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6571            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6572            self._view.ui.txt_pred_analysis_multi_prot_seq,
6573            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6574            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6575            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6576            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6577            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6578            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6579            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6580            self._view.ui.btn_pred_analysis_multi_back_2,
6581            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6582            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6583            self._view.ui.btn_pred_analysis_multi_advanced_config,
6584            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6585            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6586        ]
6587        gui_utils.show_gui_elements(gui_elements_to_show)
6588        gui_utils.hide_gui_elements(gui_elements_to_hide)
6589        gui_utils.enable_text_box(
6590            self._view.ui.txt_pred_analysis_multi_prot_name,
6591            self._view.ui.lbl_pred_analysis_multi_prot_name,
6592        )
6593        gui_utils.disable_text_box(
6594            self._view.ui.txt_pred_analysis_multi_prot_seq,
6595            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6596        )
6597        self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6598        self._view.ui.txt_pred_analysis_multi_prot_name.clear()
6599        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6600        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() > 0:
6601            try:
6602                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentItem().setSelected(False)
6603            except AttributeError:
6604                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")
6605
6606    def multi_pred_analysis_back(self) -> None:
6607        """Hides the gui elements for the protein name."""
6608        gui_elements_to_show = [
6609            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6610            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6611            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6612        ]
6613        gui_elements_to_hide = [
6614            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6615            self._view.ui.lbl_pred_analysis_multi_prot_name,
6616            self._view.ui.txt_pred_analysis_multi_prot_name,
6617            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6618            self._view.ui.btn_pred_analysis_multi_back,
6619            self._view.ui.btn_pred_analysis_multi_next,
6620            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6621            self._view.ui.txt_pred_analysis_multi_prot_seq,
6622            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6623            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6624            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6625            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6626            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6627            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6628            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6629            self._view.ui.btn_pred_analysis_multi_back_2,
6630            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6631            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6632            self._view.ui.btn_pred_analysis_multi_advanced_config,
6633            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6634            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6635        ]
6636        gui_utils.show_gui_elements(gui_elements_to_show)
6637        gui_utils.hide_gui_elements(gui_elements_to_hide)
6638        self.multi_pred_analysis_check_if_table_is_empty()
6639
6640    def multi_pred_analysis_next(self) -> None:
6641        """Shows the gui elements for the protein sequence."""
6642        gui_elements_to_show = [
6643            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6644            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6645            self._view.ui.lbl_pred_analysis_multi_prot_name,
6646            self._view.ui.txt_pred_analysis_multi_prot_name,
6647            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6648            self._view.ui.txt_pred_analysis_multi_prot_seq,
6649            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6650            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6651            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6652            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6653            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6654            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6655            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6656            self._view.ui.btn_pred_analysis_multi_back_2,
6657            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6658        ]
6659        gui_elements_to_hide = [
6660            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6661            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6662            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6663            self._view.ui.btn_pred_analysis_multi_back,
6664            self._view.ui.btn_pred_analysis_multi_next,
6665            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6666            self._view.ui.btn_pred_analysis_multi_advanced_config,
6667            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6668            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6669        ]
6670        gui_utils.show_gui_elements(gui_elements_to_show)
6671        gui_utils.hide_gui_elements(gui_elements_to_hide)
6672        gui_utils.enable_text_box(
6673            self._view.ui.txt_pred_analysis_multi_prot_seq,
6674            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6675        )
6676        gui_utils.disable_text_box(
6677            self._view.ui.txt_pred_analysis_multi_prot_name,
6678            self._view.ui.lbl_pred_analysis_multi_prot_name,
6679        )
6680        self._view.ui.txt_pred_analysis_multi_prot_seq.clear()
6681        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clear()
6682        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6683        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)
6684        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2)
6685
6686    def multi_pred_analysis_back_2(self) -> None:
6687        """Hides the gui elements for the protein sequence."""
6688        gui_elements_to_show = [
6689            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6690            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6691            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6692            self._view.ui.btn_pred_analysis_multi_back,
6693            self._view.ui.btn_pred_analysis_multi_next,
6694            self._view.ui.lbl_pred_analysis_multi_prot_name,
6695            self._view.ui.txt_pred_analysis_multi_prot_name,
6696        ]
6697        gui_elements_to_hide = [
6698            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6699            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6700            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6701            self._view.ui.txt_pred_analysis_multi_prot_seq,
6702            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6703            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6704            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6705            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6706            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6707            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6708            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6709            self._view.ui.btn_pred_analysis_multi_back_2,
6710            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6711            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6712            self._view.ui.btn_pred_analysis_multi_advanced_config,
6713            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6714            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6715        ]
6716        gui_utils.show_gui_elements(gui_elements_to_show)
6717        gui_utils.hide_gui_elements(gui_elements_to_hide)
6718        gui_utils.enable_text_box(
6719            self._view.ui.txt_pred_analysis_multi_prot_name,
6720            self._view.ui.lbl_pred_analysis_multi_prot_name,
6721        )
6722        gui_utils.disable_text_box(
6723            self._view.ui.txt_pred_analysis_multi_prot_seq,
6724            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6725        )
6726
6727    def multi_pred_analysis_prot_seq_overview_item_changed(self) -> None:
6728        """Enables the remove button of the list of sequences of the protein."""
6729        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(True)
6730
6731    def multi_pred_analysis_prot_to_predict_item_changed(self) -> None:
6732        """Enables the remove button of the list of proteins to predict."""
6733        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(True)
6734
6735    # </editor-fold>
6736
6737    def switch_multimer_pred_analysis_tab(self) -> None:
6738        """Switches the tabs from prediction to analysis and vice versa."""
6739        if self._view.ui.tabWidget_2.currentIndex() == 0:
6740            # goes from prediction to analysis
6741            self._view.ui.tabWidget_2.setCurrentIndex(1)
6742            gui_elements_to_show = [
6743                self._view.ui.lbl_pred_analysis_multi_overview,
6744                self._view.ui.list_pred_analysis_multi_overview,
6745                self._view.ui.btn_pred_analysis_multi_add,
6746                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6747            ]
6748            gui_elements_to_hide = [
6749                self._view.ui.btn_pred_analysis_multi_remove,
6750                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6751                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6752                self._view.ui.lbl_analysis_batch_vs_3,
6753                self._view.ui.lbl_pred_analysis_multi_ref_chains,
6754                self._view.ui.list_pred_analysis_multi_ref_chains,
6755                self._view.ui.btn_pred_analysis_multi_back_4,
6756                self._view.ui.btn_pred_analysis_multi_next_3,
6757                self._view.ui.box_pred_analysis_multi_prot_struct_1,
6758                self._view.ui.box_pred_analysis_multi_prot_struct_2,
6759                self._view.ui.btn_pred_analysis_multi_back_3,
6760                self._view.ui.btn_pred_analysis_multi_next_2,
6761                self._view.ui.lbl_pred_analysis_multi_model_chains,
6762                self._view.ui.list_pred_analysis_multi_model_chains,
6763                self._view.ui.btn_pred_analysis_multi_back_5,
6764                self._view.ui.btn_pred_analysis_multi_next_4,
6765                self._view.ui.lbl_pred_analysis_multi_images,
6766                self._view.ui.cb_pred_analysis_multi_images,
6767                self._view.ui.btn_pred_analysis_multi_start,
6768            ]
6769            gui_utils.show_gui_elements(gui_elements_to_show)
6770            gui_utils.hide_gui_elements(gui_elements_to_hide)
6771            self._view.ui.tabWidget_2.setTabEnabled(1, True)
6772            self._view.ui.tabWidget_2.setTabEnabled(0, False)
6773            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6774                self._view.ui.btn_pred_analysis_multi_remove.show()
6775                self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6776                self._view.ui.btn_pred_analysis_multi_start.show()
6777                self._view.ui.lbl_pred_analysis_multi_images.show()
6778                self._view.ui.cb_pred_analysis_multi_images.show()
6779        else:
6780            # goes from analysis to prediction
6781            self._view.ui.tabWidget_2.setCurrentIndex(0)
6782            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6783                gui_elements_to_show = [
6784                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6785                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6786                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6787                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6788                ]
6789                gui_elements_to_hide = [
6790                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6791                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6792                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6793                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6794                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6795                    self._view.ui.txt_pred_analysis_multi_prot_name,
6796                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6797                    self._view.ui.btn_pred_analysis_multi_back,
6798                    self._view.ui.btn_pred_analysis_multi_next,
6799                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6800                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6801                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6802                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6803                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6804                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6805                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6806                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6807                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6808                    self._view.ui.btn_pred_analysis_multi_back_2,
6809                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6810                ]
6811                gui_utils.show_gui_elements(gui_elements_to_show)
6812                gui_utils.hide_gui_elements(gui_elements_to_hide)
6813            else:
6814                gui_elements_to_show = [
6815                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6816                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6817                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6818                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6819                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6820                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6821                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6822                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6823                ]
6824                gui_elements_to_hide = [
6825                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6826                    self._view.ui.txt_pred_analysis_multi_prot_name,
6827                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6828                    self._view.ui.btn_pred_analysis_multi_back,
6829                    self._view.ui.btn_pred_analysis_multi_next,
6830                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6831                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6832                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6833                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6834                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6835                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6836                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6837                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6838                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6839                    self._view.ui.btn_pred_analysis_multi_back_2,
6840                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6841                ]
6842                gui_utils.show_gui_elements(gui_elements_to_show)
6843                gui_utils.hide_gui_elements(gui_elements_to_hide)
6844            self._view.ui.tabWidget_2.setTabEnabled(0, True)
6845            self._view.ui.tabWidget_2.setTabEnabled(1, False)
6846
6847    # <editor-fold desc="Analysis section">
6848    def multi_pred_analysis_structure_analysis_add(self) -> None:
6849        """Shows the gui elements to choose the two proteins."""
6850        gui_elements_to_show = [
6851            self._view.ui.lbl_pred_analysis_multi_overview,
6852            self._view.ui.list_pred_analysis_multi_overview,
6853            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6854            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6855            self._view.ui.lbl_analysis_batch_vs_3,
6856            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6857            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6858            self._view.ui.btn_pred_analysis_multi_back_3,
6859            self._view.ui.btn_pred_analysis_multi_next_2,
6860        ]
6861        gui_elements_to_hide = [
6862            self._view.ui.btn_pred_analysis_multi_remove,
6863            self._view.ui.btn_pred_analysis_multi_add,
6864            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6865            self._view.ui.list_pred_analysis_multi_ref_chains,
6866            self._view.ui.btn_pred_analysis_multi_back_4,
6867            self._view.ui.btn_pred_analysis_multi_next_3,
6868            self._view.ui.lbl_pred_analysis_multi_model_chains,
6869            self._view.ui.list_pred_analysis_multi_model_chains,
6870            self._view.ui.btn_pred_analysis_multi_back_5,
6871            self._view.ui.btn_pred_analysis_multi_next_4,
6872            self._view.ui.lbl_pred_analysis_multi_images,
6873            self._view.ui.cb_pred_analysis_multi_images,
6874            self._view.ui.btn_pred_analysis_multi_start,
6875            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6876        ]
6877        gui_utils.show_gui_elements(gui_elements_to_show)
6878        gui_utils.hide_gui_elements(gui_elements_to_hide)
6879        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.clear()
6880        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.clear()
6881        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
6882        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")
6883        self.fill_multi_pred_analysis_protein_boxes()
6884        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6885            try:
6886                self._view.ui.list_pred_analysis_multi_overview.currentItem().setSelected(False)
6887            except AttributeError:
6888                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
6889
6890    def multi_pred_analysis_structure_analysis_back_3(self) -> None:
6891        """Hides the gui elements to choose the two proteins."""
6892        gui_elements_to_show = [
6893            self._view.ui.lbl_pred_analysis_multi_overview,
6894            self._view.ui.list_pred_analysis_multi_overview,
6895            self._view.ui.btn_pred_analysis_multi_add,
6896            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6897        ]
6898        gui_elements_to_hide = [
6899            self._view.ui.btn_pred_analysis_multi_remove,
6900            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6901            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6902            self._view.ui.lbl_analysis_batch_vs_3,
6903            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6904            self._view.ui.list_pred_analysis_multi_ref_chains,
6905            self._view.ui.btn_pred_analysis_multi_back_4,
6906            self._view.ui.btn_pred_analysis_multi_next_3,
6907            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6908            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6909            self._view.ui.btn_pred_analysis_multi_back_3,
6910            self._view.ui.btn_pred_analysis_multi_next_2,
6911            self._view.ui.lbl_pred_analysis_multi_model_chains,
6912            self._view.ui.list_pred_analysis_multi_model_chains,
6913            self._view.ui.btn_pred_analysis_multi_back_5,
6914            self._view.ui.btn_pred_analysis_multi_next_4,
6915            self._view.ui.lbl_pred_analysis_multi_images,
6916            self._view.ui.cb_pred_analysis_multi_images,
6917            self._view.ui.btn_pred_analysis_multi_start,
6918        ]
6919        gui_utils.show_gui_elements(gui_elements_to_show)
6920        gui_utils.hide_gui_elements(gui_elements_to_hide)
6921        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6922            self._view.ui.btn_pred_analysis_multi_remove.show()
6923            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6924            self._view.ui.btn_pred_analysis_multi_start.show()
6925            self._view.ui.lbl_pred_analysis_multi_images.show()
6926            self._view.ui.cb_pred_analysis_multi_images.show()
6927
6928    def multi_pred_analysis_structure_analysis_next_3(self) -> None:
6929        """Shows the gui elements to select the chains in protein 2."""
6930        gui_elements_to_show = [
6931            self._view.ui.lbl_pred_analysis_multi_overview,
6932            self._view.ui.list_pred_analysis_multi_overview,
6933            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6934            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6935            self._view.ui.lbl_analysis_batch_vs_3,
6936            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6937            self._view.ui.list_pred_analysis_multi_ref_chains,
6938            self._view.ui.lbl_pred_analysis_multi_model_chains,
6939            self._view.ui.list_pred_analysis_multi_model_chains,
6940            self._view.ui.btn_pred_analysis_multi_back_5,
6941            self._view.ui.btn_pred_analysis_multi_next_4,
6942        ]
6943        gui_elements_to_hide = [
6944            self._view.ui.btn_pred_analysis_multi_remove,
6945            self._view.ui.btn_pred_analysis_multi_add,
6946            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6947            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6948            self._view.ui.btn_pred_analysis_multi_back_3,
6949            self._view.ui.btn_pred_analysis_multi_next_2,
6950            self._view.ui.btn_pred_analysis_multi_back_4,
6951            self._view.ui.btn_pred_analysis_multi_next_3,
6952            self._view.ui.lbl_pred_analysis_multi_images,
6953            self._view.ui.cb_pred_analysis_multi_images,
6954            self._view.ui.btn_pred_analysis_multi_start,
6955            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6956        ]
6957        gui_utils.show_gui_elements(gui_elements_to_show)
6958        gui_utils.hide_gui_elements(gui_elements_to_hide)
6959        self._view.ui.list_pred_analysis_multi_model_chains.clear()
6960        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(False)
6961        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
6962
6963        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6964            if (
6965                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text()
6966                == self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText()
6967            ):
6968                self._view.ui.list_pred_analysis_multi_model_chains.addItem(
6969                    self._view.ui.table_pred_analysis_multi_prot_to_predict.item(i, 0).text(),
6970                )
6971        if self._view.ui.list_pred_analysis_multi_model_chains.count() == 0:
6972            tmp_protein = self._current_project.search_protein(
6973                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
6974            )
6975            for tmp_chain in tmp_protein.chains:
6976                if tmp_chain.chain_type == "protein_chain":
6977                    self._view.ui.list_pred_analysis_multi_model_chains.addItem(tmp_chain.chain_letter)
6978        if len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems()) == 1:
6979            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6980                f"Select 1 chain in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6981            )
6982        else:
6983            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6984                f"Select {len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())} chains in "
6985                f"protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6986            )
6987
6988    def multi_pred_analysis_structure_analysis_back_4(self) -> None:
6989        """Hides the gui elements to select the chains in protein 1."""
6990        gui_elements_to_show = [
6991            self._view.ui.lbl_pred_analysis_multi_overview,
6992            self._view.ui.list_pred_analysis_multi_overview,
6993            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6994            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6995            self._view.ui.lbl_analysis_batch_vs_3,
6996            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6997            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6998            self._view.ui.btn_pred_analysis_multi_back_3,
6999            self._view.ui.btn_pred_analysis_multi_next_2,
7000            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7001        ]
7002        gui_elements_to_hide = [
7003            self._view.ui.btn_pred_analysis_multi_remove,
7004            self._view.ui.btn_pred_analysis_multi_add,
7005            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7006            self._view.ui.list_pred_analysis_multi_ref_chains,
7007            self._view.ui.btn_pred_analysis_multi_back_4,
7008            self._view.ui.btn_pred_analysis_multi_next_3,
7009            self._view.ui.lbl_pred_analysis_multi_model_chains,
7010            self._view.ui.list_pred_analysis_multi_model_chains,
7011            self._view.ui.btn_pred_analysis_multi_back_5,
7012            self._view.ui.btn_pred_analysis_multi_next_4,
7013            self._view.ui.lbl_pred_analysis_multi_images,
7014            self._view.ui.cb_pred_analysis_multi_images,
7015            self._view.ui.btn_pred_analysis_multi_start,
7016        ]
7017        gui_utils.show_gui_elements(gui_elements_to_show)
7018        gui_utils.hide_gui_elements(gui_elements_to_hide)
7019        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
7020        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")
7021
7022    def multi_pred_analysis_structure_analysis_next_4(self) -> None:
7023        """Adds the protein pair to the list of protein pairs to analyze."""
7024        gui_elements_to_show = [
7025            self._view.ui.btn_pred_analysis_multi_remove,
7026            self._view.ui.btn_pred_analysis_multi_add,
7027            self._view.ui.lbl_pred_analysis_multi_overview,
7028            self._view.ui.list_pred_analysis_multi_overview,
7029            self._view.ui.lbl_pred_analysis_multi_images,
7030            self._view.ui.cb_pred_analysis_multi_images,
7031            self._view.ui.btn_pred_analysis_multi_start,
7032            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7033        ]
7034        gui_elements_to_hide = [
7035            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7036            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7037            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7038            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7039            self._view.ui.lbl_analysis_batch_vs_3,
7040            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7041            self._view.ui.list_pred_analysis_multi_ref_chains,
7042            self._view.ui.lbl_pred_analysis_multi_model_chains,
7043            self._view.ui.list_pred_analysis_multi_model_chains,
7044            self._view.ui.btn_pred_analysis_multi_back_3,
7045            self._view.ui.btn_pred_analysis_multi_next_2,
7046            self._view.ui.btn_pred_analysis_multi_back_4,
7047            self._view.ui.btn_pred_analysis_multi_next_3,
7048            self._view.ui.btn_pred_analysis_multi_back_5,
7049            self._view.ui.btn_pred_analysis_multi_next_4,
7050        ]
7051        gui_utils.show_gui_elements(gui_elements_to_show)
7052        gui_utils.hide_gui_elements(gui_elements_to_hide)
7053        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7054        prot_1_chains = []
7055        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7056            prot_1_chains.append(chain.text())
7057        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7058        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7059        prot_2_chains = []
7060        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7061            prot_2_chains.append(chain.text())
7062        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7063        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7064        item = QtWidgets.QListWidgetItem(analysis_name)
7065        self._view.ui.list_pred_analysis_multi_overview.addItem(item)
7066        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
7067
7068    def multi_pred_analysis_structure_analysis_back_5(self) -> None:
7069        """Hides the gui elements to select the chains in protein 2."""
7070        gui_elements_to_show = [
7071            self._view.ui.lbl_pred_analysis_multi_overview,
7072            self._view.ui.list_pred_analysis_multi_overview,
7073            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7074            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7075            self._view.ui.lbl_analysis_batch_vs_3,
7076            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7077            self._view.ui.list_pred_analysis_multi_ref_chains,
7078            self._view.ui.btn_pred_analysis_multi_back_4,
7079            self._view.ui.btn_pred_analysis_multi_next_3,
7080        ]
7081        gui_elements_to_hide = [
7082            self._view.ui.btn_pred_analysis_multi_remove,
7083            self._view.ui.btn_pred_analysis_multi_add,
7084            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7085            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7086            self._view.ui.btn_pred_analysis_multi_back_3,
7087            self._view.ui.btn_pred_analysis_multi_next_2,
7088            self._view.ui.btn_pred_analysis_multi_back_5,
7089            self._view.ui.btn_pred_analysis_multi_next_4,
7090            self._view.ui.lbl_pred_analysis_multi_images,
7091            self._view.ui.cb_pred_analysis_multi_images,
7092            self._view.ui.btn_pred_analysis_multi_start,
7093            self._view.ui.lbl_pred_analysis_multi_model_chains,
7094            self._view.ui.list_pred_analysis_multi_model_chains,
7095            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7096        ]
7097        gui_utils.show_gui_elements(gui_elements_to_show)
7098        gui_utils.hide_gui_elements(gui_elements_to_hide)
7099        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(True)
7100
7101        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText())
7102        # for tmp_chain in tmp_protein.chains:
7103        #     if tmp_chain.chain_type == "protein_chain":
7104        #         self._view.ui.list_pred_analysis_multi_ref_chains.addItem(tmp_chain.chain_letter)
7105
7106    def multi_pred_analysis_structure_analysis_overview_clicked(self) -> None:
7107        """Enables the remove button."""
7108        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(True)
7109
7110    def fill_multi_pred_analysis_protein_boxes(self) -> None:
7111        """Fills the combo boxes with the protein names."""
7112        protein_names = []
7113        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
7114            protein_names.append(self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text())
7115        for tmp_protein in self._current_project.proteins:
7116            protein_names.append(tmp_protein.get_molecule_object())
7117        protein_names.insert(0, "")
7118        protein_names = list(set(protein_names))
7119        self._view.ui.box_pred_analysis_multi_prot_struct_1.clear()
7120        self._view.ui.box_pred_analysis_multi_prot_struct_2.clear()
7121        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_1, protein_names)
7122        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_2, protein_names)
7123
7124    def remove_multi_pred_analysis_analysis_run(self) -> None:
7125        """Removes the selected protein pair from the list of protein pairs to analyze."""
7126        self._view.ui.list_pred_analysis_multi_overview.takeItem(
7127            self._view.ui.list_pred_analysis_multi_overview.currentRow(),
7128        )
7129        gui_elements_to_show = [
7130            self._view.ui.lbl_pred_analysis_multi_overview,
7131            self._view.ui.list_pred_analysis_multi_overview,
7132            self._view.ui.btn_pred_analysis_multi_add,
7133            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7134        ]
7135        gui_elements_to_hide = [
7136            self._view.ui.btn_pred_analysis_multi_remove,
7137            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7138            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7139            self._view.ui.lbl_analysis_batch_vs_3,
7140            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7141            self._view.ui.list_pred_analysis_multi_ref_chains,
7142            self._view.ui.btn_pred_analysis_multi_back_4,
7143            self._view.ui.btn_pred_analysis_multi_next_3,
7144            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7145            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7146            self._view.ui.btn_pred_analysis_multi_back_3,
7147            self._view.ui.btn_pred_analysis_multi_next_2,
7148            self._view.ui.lbl_pred_analysis_multi_model_chains,
7149            self._view.ui.list_pred_analysis_multi_model_chains,
7150            self._view.ui.btn_pred_analysis_multi_back_5,
7151            self._view.ui.btn_pred_analysis_multi_next_4,
7152            self._view.ui.lbl_pred_analysis_multi_images,
7153            self._view.ui.cb_pred_analysis_multi_images,
7154            self._view.ui.btn_pred_analysis_multi_start,
7155        ]
7156        gui_utils.show_gui_elements(gui_elements_to_show)
7157        gui_utils.hide_gui_elements(gui_elements_to_hide)
7158        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
7159            self._view.ui.btn_pred_analysis_multi_remove.show()
7160            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
7161            self._view.ui.btn_pred_analysis_multi_start.show()
7162            self._view.ui.lbl_pred_analysis_multi_images.show()
7163            self._view.ui.cb_pred_analysis_multi_images.show()
7164        # if self._view.ui.list_pred_analysis_multi_overview.count() == 0:
7165        #
7166        #     self._view.ui.btn_pred_analysis_multi_back_pred_setup.show()
7167        #     self._view.ui.btn_pred_analysis_multi_remove.hide()
7168
7169    def check_multi_pred_analysis_if_same_no_of_chains_selected(self) -> None:
7170        """Checks if the same number of chains were selected."""
7171        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7172        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_multi_model_chains.selectedItems()):
7173            self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(True)
7174
7175        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7176        prot_1_chains = []
7177        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7178            prot_1_chains.append(chain.text())
7179        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7180        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7181        prot_2_chains = []
7182        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7183            prot_2_chains.append(chain.text())
7184        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7185        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7186        for tmp_row in range(self._view.ui.list_pred_analysis_multi_overview.count()):
7187            if analysis_name == self._view.ui.list_pred_analysis_multi_overview.item(tmp_row).text():
7188                self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7189                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next_4)
7190                return
7191
7192    def check_multi_pred_analysis_if_prot_structs_are_filled(self) -> None:
7193        """Checks if two proteins were selected."""
7194        prot_1 = self._view.ui.box_pred_analysis_multi_prot_struct_1.itemText(
7195            self._view.ui.box_pred_analysis_multi_prot_struct_1.currentIndex(),
7196        )
7197        prot_2 = self._view.ui.box_pred_analysis_multi_prot_struct_2.itemText(
7198            self._view.ui.box_pred_analysis_multi_prot_struct_2.currentIndex(),
7199        )
7200        if prot_1 != "" and prot_2 != "":
7201            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(True)
7202        else:
7203            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(False)
7204
7205    def count_multi_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
7206        """Counts the number of chains in protein 1."""
7207        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())
7208        if self.no_of_selected_chains > 0:
7209            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(True)
7210        else:
7211            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(False)
7212
7213    # </editor-fold>
7214    # </editor-fold>
7215
7216    # <editor-fold desc="Distance analysis">
7217    def structure_analysis_add(self) -> None:
7218        """Shows the gui elements to choose the two proteins."""
7219        gui_elements_to_show = [
7220            self._view.ui.lbl_analysis_batch_overview,
7221            self._view.ui.list_analysis_batch_overview,
7222            self._view.ui.lbl_analysis_batch_prot_struct_1,
7223            self._view.ui.box_analysis_batch_prot_struct_1,
7224            self._view.ui.lbl_analysis_batch_vs,
7225            self._view.ui.lbl_analysis_batch_prot_struct_2,
7226            self._view.ui.box_analysis_batch_prot_struct_2,
7227            self._view.ui.btn_analysis_batch_back,
7228            self._view.ui.btn_analysis_batch_next,
7229        ]
7230        gui_elements_to_hide = [
7231            self._view.ui.btn_analysis_batch_remove,
7232            self._view.ui.btn_analysis_batch_add,
7233            self._view.ui.lbl_analysis_batch_ref_chains,
7234            self._view.ui.list_analysis_batch_ref_chains,
7235            self._view.ui.btn_analysis_batch_back_2,
7236            self._view.ui.btn_analysis_batch_next_2,
7237            self._view.ui.lbl_analysis_batch_model_chains,
7238            self._view.ui.list_analysis_batch_model_chains,
7239            self._view.ui.btn_analysis_batch_back_3,
7240            self._view.ui.btn_analysis_batch_next_3,
7241            self._view.ui.lbl_analysis_batch_images,
7242            self._view.ui.cb_analysis_batch_images,
7243            self._view.ui.btn_analysis_batch_start,
7244        ]
7245
7246        gui_utils.show_gui_elements(gui_elements_to_show)
7247        gui_utils.hide_gui_elements(gui_elements_to_hide)
7248        self._view.ui.lbl_analysis_batch_prot_struct_1.clear()
7249        self._view.ui.lbl_analysis_batch_prot_struct_2.clear()
7250        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7251        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")
7252        self.fill_protein_boxes_batch()
7253        if self._view.ui.list_analysis_batch_overview.count() > 0:
7254            try:
7255                self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7256            except AttributeError:
7257                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
7258
7259    def structure_analysis_back(self) -> None:
7260        """Hides the gui elements to choose the two proteins."""
7261        gui_elements_to_show = [
7262            self._view.ui.lbl_analysis_batch_overview,
7263            self._view.ui.list_analysis_batch_overview,
7264            self._view.ui.btn_analysis_batch_add,
7265        ]
7266        gui_elements_to_hide = [
7267            self._view.ui.btn_analysis_batch_remove,
7268            self._view.ui.lbl_analysis_batch_prot_struct_1,
7269            self._view.ui.lbl_analysis_batch_prot_struct_2,
7270            self._view.ui.lbl_analysis_batch_vs,
7271            self._view.ui.lbl_analysis_batch_ref_chains,
7272            self._view.ui.list_analysis_batch_ref_chains,
7273            self._view.ui.btn_analysis_batch_back_2,
7274            self._view.ui.btn_analysis_batch_next_2,
7275            self._view.ui.box_analysis_batch_prot_struct_1,
7276            self._view.ui.box_analysis_batch_prot_struct_2,
7277            self._view.ui.btn_analysis_batch_back,
7278            self._view.ui.btn_analysis_batch_next,
7279            self._view.ui.lbl_analysis_batch_model_chains,
7280            self._view.ui.list_analysis_batch_model_chains,
7281            self._view.ui.btn_analysis_batch_back_3,
7282            self._view.ui.btn_analysis_batch_next_3,
7283            self._view.ui.lbl_analysis_batch_images,
7284            self._view.ui.cb_analysis_batch_images,
7285            self._view.ui.btn_analysis_batch_start,
7286        ]
7287        gui_utils.show_gui_elements(gui_elements_to_show)
7288        gui_utils.hide_gui_elements(gui_elements_to_hide)
7289        if self._view.ui.list_analysis_batch_overview.count() > 0:
7290            self._view.ui.btn_analysis_batch_remove.show()
7291            self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7292            self._view.ui.btn_analysis_batch_start.show()
7293            self._view.ui.lbl_analysis_batch_images.show()
7294            self._view.ui.cb_analysis_batch_images.show()
7295
7296    def structure_analysis_next_2(self) -> None:
7297        """Shows the gui elements to select the chains in protein 2."""
7298        gui_elements_to_show = [
7299            self._view.ui.lbl_analysis_batch_overview,
7300            self._view.ui.list_analysis_batch_overview,
7301            self._view.ui.lbl_analysis_batch_prot_struct_1,
7302            self._view.ui.lbl_analysis_batch_prot_struct_2,
7303            self._view.ui.lbl_analysis_batch_vs,
7304            self._view.ui.lbl_analysis_batch_ref_chains,
7305            self._view.ui.list_analysis_batch_ref_chains,
7306            self._view.ui.lbl_analysis_batch_model_chains,
7307            self._view.ui.list_analysis_batch_model_chains,
7308            self._view.ui.btn_analysis_batch_back_3,
7309            self._view.ui.btn_analysis_batch_next_3,
7310        ]
7311        gui_elements_to_hide = [
7312            self._view.ui.btn_analysis_batch_remove,
7313            self._view.ui.btn_analysis_batch_add,
7314            self._view.ui.box_analysis_batch_prot_struct_1,
7315            self._view.ui.box_analysis_batch_prot_struct_2,
7316            self._view.ui.btn_analysis_batch_back,
7317            self._view.ui.btn_analysis_batch_next,
7318            self._view.ui.btn_analysis_batch_back_2,
7319            self._view.ui.btn_analysis_batch_next_2,
7320            self._view.ui.lbl_analysis_batch_images,
7321            self._view.ui.cb_analysis_batch_images,
7322            self._view.ui.btn_analysis_batch_start,
7323        ]
7324        gui_utils.show_gui_elements(gui_elements_to_show)
7325        gui_utils.hide_gui_elements(gui_elements_to_hide)
7326        self._view.ui.list_analysis_batch_model_chains.clear()
7327        self._view.ui.list_analysis_batch_ref_chains.setEnabled(False)
7328        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7329
7330        tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7331        for tmp_chain in tmp_protein.chains:
7332            if tmp_chain.chain_type == "protein_chain":
7333                self._view.ui.list_analysis_batch_model_chains.addItem(tmp_chain.chain_letter)
7334        if len(self._view.ui.list_analysis_batch_ref_chains.selectedItems()) == 1:
7335            self._view.ui.lbl_analysis_batch_model_chains.setText(
7336                f"Select 1 chain in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7337            )
7338        else:
7339            self._view.ui.lbl_analysis_batch_model_chains.setText(
7340                f"Select {len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())} chains in "
7341                f"protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7342            )
7343
7344    def structure_analysis_back_2(self) -> None:
7345        """Hides the gui elements to select the chains in protein 1."""
7346        gui_elements_to_show = [
7347            self._view.ui.lbl_analysis_batch_overview,
7348            self._view.ui.list_analysis_batch_overview,
7349            self._view.ui.lbl_analysis_batch_prot_struct_1,
7350            self._view.ui.box_analysis_batch_prot_struct_1,
7351            self._view.ui.lbl_analysis_batch_vs,
7352            self._view.ui.lbl_analysis_batch_prot_struct_2,
7353            self._view.ui.box_analysis_batch_prot_struct_2,
7354            self._view.ui.btn_analysis_batch_back,
7355            self._view.ui.btn_analysis_batch_next,
7356        ]
7357        gui_elements_to_hide = [
7358            self._view.ui.btn_analysis_batch_remove,
7359            self._view.ui.btn_analysis_batch_add,
7360            self._view.ui.lbl_analysis_batch_ref_chains,
7361            self._view.ui.list_analysis_batch_ref_chains,
7362            self._view.ui.btn_analysis_batch_back_2,
7363            self._view.ui.btn_analysis_batch_next_2,
7364            self._view.ui.lbl_analysis_batch_model_chains,
7365            self._view.ui.list_analysis_batch_model_chains,
7366            self._view.ui.btn_analysis_batch_back_3,
7367            self._view.ui.btn_analysis_batch_next_3,
7368            self._view.ui.lbl_analysis_batch_images,
7369            self._view.ui.cb_analysis_batch_images,
7370            self._view.ui.btn_analysis_batch_start,
7371        ]
7372        gui_utils.show_gui_elements(gui_elements_to_show)
7373        gui_utils.hide_gui_elements(gui_elements_to_hide)
7374        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7375        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")
7376
7377    def structure_analysis_next_3(self) -> None:
7378        """Adds the protein pair to the list of protein pairs to analyze."""
7379        gui_elements_to_show = [
7380            self._view.ui.btn_analysis_batch_remove,
7381            self._view.ui.btn_analysis_batch_add,
7382            self._view.ui.lbl_analysis_batch_overview,
7383            self._view.ui.list_analysis_batch_overview,
7384            self._view.ui.lbl_analysis_batch_images,
7385            self._view.ui.cb_analysis_batch_images,
7386            self._view.ui.btn_analysis_batch_start,
7387        ]
7388        gui_elements_to_hide = [
7389            self._view.ui.box_analysis_batch_prot_struct_1,
7390            self._view.ui.box_analysis_batch_prot_struct_2,
7391            self._view.ui.lbl_analysis_batch_prot_struct_1,
7392            self._view.ui.lbl_analysis_batch_prot_struct_2,
7393            self._view.ui.lbl_analysis_batch_vs,
7394            self._view.ui.lbl_analysis_batch_ref_chains,
7395            self._view.ui.list_analysis_batch_ref_chains,
7396            self._view.ui.lbl_analysis_batch_model_chains,
7397            self._view.ui.list_analysis_batch_model_chains,
7398            self._view.ui.btn_analysis_batch_back,
7399            self._view.ui.btn_analysis_batch_next,
7400            self._view.ui.btn_analysis_batch_back_2,
7401            self._view.ui.btn_analysis_batch_next_2,
7402            self._view.ui.btn_analysis_batch_back_3,
7403            self._view.ui.btn_analysis_batch_next_3,
7404        ]
7405        gui_utils.show_gui_elements(gui_elements_to_show)
7406        gui_utils.hide_gui_elements(gui_elements_to_hide)
7407        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7408        prot_1_chains = []
7409        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7410            prot_1_chains.append(chain.text())
7411        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7412        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7413        prot_2_chains = []
7414        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7415            prot_2_chains.append(chain.text())
7416        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7417        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7418        item = QtWidgets.QListWidgetItem(analysis_name)
7419        self._view.ui.list_analysis_batch_overview.addItem(item)
7420        self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7421
7422    def structure_analysis_back_3(self) -> None:
7423        """Hides the gui elements to select the chains in protein 2."""
7424        gui_elements_to_show = [
7425            self._view.ui.lbl_analysis_batch_overview,
7426            self._view.ui.list_analysis_batch_overview,
7427            self._view.ui.lbl_analysis_batch_prot_struct_1,
7428            self._view.ui.lbl_analysis_batch_prot_struct_2,
7429            self._view.ui.lbl_analysis_batch_vs,
7430            self._view.ui.lbl_analysis_batch_ref_chains,
7431            self._view.ui.list_analysis_batch_ref_chains,
7432            self._view.ui.btn_analysis_batch_back_2,
7433            self._view.ui.btn_analysis_batch_next_2,
7434        ]
7435        gui_elements_to_hide = [
7436            self._view.ui.btn_analysis_batch_remove,
7437            self._view.ui.btn_analysis_batch_add,
7438            self._view.ui.box_analysis_batch_prot_struct_1,
7439            self._view.ui.box_analysis_batch_prot_struct_2,
7440            self._view.ui.btn_analysis_batch_back,
7441            self._view.ui.btn_analysis_batch_next,
7442            self._view.ui.btn_analysis_batch_back_3,
7443            self._view.ui.btn_analysis_batch_next_3,
7444            self._view.ui.lbl_analysis_batch_images,
7445            self._view.ui.cb_analysis_batch_images,
7446            self._view.ui.btn_analysis_batch_start,
7447            self._view.ui.lbl_analysis_batch_model_chains,
7448            self._view.ui.list_analysis_batch_model_chains,
7449        ]
7450        gui_utils.show_gui_elements(gui_elements_to_show)
7451        gui_utils.hide_gui_elements(gui_elements_to_hide)
7452        self._view.ui.list_analysis_batch_ref_chains.setEnabled(True)
7453
7454        # tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7455        # for tmp_chain in tmp_protein.chains:
7456        #     if tmp_chain.chain_type == "protein_chain":
7457        #         self._view.ui.list_analysis_batch_ref_chains.addItem(tmp_chain.chain_letter)
7458
7459    def structure_analysis_overview_clicked(self) -> None:
7460        """Enables the remove button."""
7461        self._view.ui.btn_analysis_batch_remove.setEnabled(True)
7462
7463    def fill_protein_boxes_batch(self) -> None:
7464        """Fills the combo boxes with the protein names."""
7465        proteins = []
7466        for tmp_protein in self._current_project.proteins:
7467            proteins.append(tmp_protein.get_molecule_object())
7468        proteins.insert(0, "")
7469        self._view.ui.box_analysis_batch_prot_struct_1.clear()
7470        self._view.ui.box_analysis_batch_prot_struct_2.clear()
7471        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_1, proteins)
7472        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_2, proteins)
7473
7474    def remove_analysis_run(self) -> None:
7475        """Removes the selected protein pair from the list of protein pairs to analyze."""
7476        self._view.ui.list_analysis_batch_overview.takeItem(self._view.ui.list_analysis_batch_overview.currentRow())
7477        if self._view.ui.list_analysis_batch_overview.count() == 0:
7478            gui_elements_to_show = [
7479                self._view.ui.lbl_analysis_batch_overview,
7480                self._view.ui.list_analysis_batch_overview,
7481                self._view.ui.btn_analysis_batch_add,
7482            ]
7483
7484            gui_elements_to_hide = [
7485                self._view.ui.btn_analysis_batch_remove,
7486                self._view.ui.lbl_analysis_batch_prot_struct_1,
7487                self._view.ui.lbl_analysis_batch_prot_struct_2,
7488                self._view.ui.lbl_analysis_batch_vs,
7489                self._view.ui.lbl_analysis_batch_ref_chains,
7490                self._view.ui.list_analysis_batch_ref_chains,
7491                self._view.ui.btn_analysis_batch_back_2,
7492                self._view.ui.btn_analysis_batch_next_2,
7493                self._view.ui.box_analysis_batch_prot_struct_1,
7494                self._view.ui.box_analysis_batch_prot_struct_2,
7495                self._view.ui.btn_analysis_batch_back,
7496                self._view.ui.btn_analysis_batch_next,
7497                self._view.ui.lbl_analysis_batch_model_chains,
7498                self._view.ui.list_analysis_batch_model_chains,
7499                self._view.ui.btn_analysis_batch_back_3,
7500                self._view.ui.btn_analysis_batch_next_3,
7501                self._view.ui.lbl_analysis_batch_images,
7502                self._view.ui.cb_analysis_batch_images,
7503                self._view.ui.btn_analysis_batch_start,
7504            ]
7505
7506            gui_utils.show_gui_elements(gui_elements_to_show)
7507            gui_utils.hide_gui_elements(gui_elements_to_hide)
7508            self._view.ui.btn_analysis_batch_remove.hide()
7509        else:
7510            if self._view.ui.list_analysis_batch_overview.count() > 0:
7511                try:
7512                    self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7513                except AttributeError:
7514                    constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
7515        self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7516
7517    def check_if_same_no_of_chains_selected_batch(self) -> None:
7518        """Checks if the same number of proteins were selected."""
7519        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7520        if self.no_of_selected_chains == len(self._view.ui.list_analysis_batch_model_chains.selectedItems()):
7521            self._view.ui.btn_analysis_batch_next_3.setEnabled(True)
7522
7523        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7524        prot_1_chains = []
7525        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7526            prot_1_chains.append(chain.text())
7527        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7528        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7529        prot_2_chains = []
7530        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7531            prot_2_chains.append(chain.text())
7532        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7533        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7534        for tmp_row in range(self._view.ui.list_analysis_batch_overview.count()):
7535            if analysis_name == self._view.ui.list_analysis_batch_overview.item(tmp_row).text():
7536                self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7537                styles.color_button_not_ready(self._view.ui.btn_analysis_batch_next_3)
7538                return
7539
7540    def check_if_prot_structs_are_filled_batch(self) -> None:
7541        """Checks if two proteins were selected."""
7542        prot_1 = self._view.ui.box_analysis_batch_prot_struct_1.itemText(
7543            self._view.ui.box_analysis_batch_prot_struct_1.currentIndex(),
7544        )
7545        prot_2 = self._view.ui.box_analysis_batch_prot_struct_2.itemText(
7546            self._view.ui.box_analysis_batch_prot_struct_2.currentIndex(),
7547        )
7548        if prot_1 != "" and prot_2 != "":
7549            self._view.ui.btn_analysis_batch_next.setEnabled(True)
7550        else:
7551            self._view.ui.btn_analysis_batch_next.setEnabled(False)
7552
7553    def count_batch_selected_chains_for_prot_struct_1(self) -> None:
7554        """Counts the number of chains of protein 1."""
7555        self.no_of_selected_chains = len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())
7556        if self.no_of_selected_chains > 0:
7557            self._view.ui.btn_analysis_batch_next_2.setEnabled(True)
7558        else:
7559            self._view.ui.btn_analysis_batch_next_2.setEnabled(False)
7560
7561    # </editor-fold>
7562
7563    # <editor-fold desc="Analysis images">
7564    def display_image_analysis_page(self) -> None:
7565        """Displays the analysis image work area."""
7566        # get all protein pairs without images
7567        self._view.ui.list_analysis_images_struct_analysis.clear()
7568        self._view.ui.list_analysis_images_creation_struct_analysis.clear()
7569        for tmp_protein_pair in self._current_project.protein_pairs:
7570            if len(tmp_protein_pair.distance_analysis.analysis_results.structure_aln_image) == 0:
7571                self._view.ui.list_analysis_images_struct_analysis.addItem(tmp_protein_pair.name)
7572        self.last_sidebar_button = styles.color_sidebar_buttons(
7573            self.last_sidebar_button,
7574            self._view.ui.btn_image_analysis_page,
7575        )
7576        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 23, "Analysis Images")
7577        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7578        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7579        self._view.ui.btn_start_automatic_image_creation.setEnabled(False)
7580
7581    def analysis_images_enable_add(self) -> None:
7582        """Enables the add button."""
7583        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(True)
7584
7585    def analysis_images_enable_remove(self) -> None:
7586        """Enables the remove button."""
7587        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(True)
7588
7589    def add_protein_pair_to_image_creation_queue(self) -> None:
7590        """Adds a protein pair from the list of protein pairs to make images of."""
7591        protein_pair_to_add = self._view.ui.list_analysis_images_struct_analysis.currentItem().text()
7592        self._view.ui.list_analysis_images_creation_struct_analysis.addItem(protein_pair_to_add)
7593        self._view.ui.list_analysis_images_struct_analysis.takeItem(
7594            self._view.ui.list_analysis_images_struct_analysis.currentRow(),
7595        )
7596        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7597        self.analysis_images_check_if_creation_can_start()
7598
7599    def remove_protein_pair_from_image_creation_queue(self) -> None:
7600        """Removes a protein pair from the list of protein pairs to make images of."""
7601        protein_pair_to_remove = self._view.ui.list_analysis_images_creation_struct_analysis.currentItem()
7602        self._view.ui.list_analysis_images_creation_struct_analysis.takeItem(
7603            self._view.ui.list_analysis_images_creation_struct_analysis.currentRow(),
7604        )
7605        self._view.ui.list_analysis_images_struct_analysis.addItem(protein_pair_to_remove)
7606        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7607        self.analysis_images_check_if_creation_can_start()
7608
7609    def analysis_images_check_if_creation_can_start(self) -> None:
7610        """Checks if the list of protein pairs which get images are empty."""
7611        if self._view.ui.list_analysis_images_creation_struct_analysis.count() > 0:
7612            self._view.ui.btn_start_automatic_image_creation.setEnabled(True)
7613        else:
7614            self._view.ui.btn_start_automatic_image_creation.setEnabled(False)
7615
7616    # </editor-fold>
7617
7618    # </editor-fold>
7619
7620    def update_status(self, message: str) -> None:
7621        """Updates the status bar of the main view with a custom message."""
7622        self._view.status_bar.showMessage(message)

Class for main presenter of the pyssa plugin.

MainPresenter(a_view: pyssa.gui.ui.views.main_view.MainView)
123    def __init__(self, a_view: "main_view.MainView") -> None:
124        """Constructor.
125
126        Args:
127            a_view: the main view of the pyssa plugin.
128
129        Raises:
130            IllegalArgumentException: If an argument is illegal.
131        """
132        # <editor-fold desc="Checks">
133        safeguard.Safeguard.check_if_value_is_not_none(a_view, logger)
134
135        # </editor-fold>
136
137        # <editor-fold desc="Initialize class attributes">
138        self._view = a_view
139        self._workspace_path = constants.DEFAULT_WORKSPACE_PATH
140        # TODO: settings and project objects get not initialized properly
141        self._application_settings = settings.Settings("", "")
142        self._current_project: "project.Project" = project.Project()
143        self._project_watcher: "project_watcher.ProjectWatcher" = project_watcher.ProjectWatcher(self._current_project)
144
145        # </editor-fold>
146
147        # Check OS
148        main_window_util.check_operating_system()
149        # Create log dir
150        # <editor-fold desc="Program directory check">
151        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa"))
152        filesystem_helpers.create_directory(pathlib.Path(f"{os.path.expanduser('~')}/.pyssa/logs"))
153        constants.PYSSA_LOGGER.info("Checked program and logs directory.")
154
155        # </editor-fold>
156        # Configure settings
157        # <editor-fold desc="Setup App Settings">
158        self._application_settings = settings.Settings(constants.SETTINGS_DIR, constants.SETTINGS_FILENAME)
159        if not os.path.exists(constants.SETTINGS_FULL_FILEPATH):
160            constants.PYSSA_LOGGER.info("Settings file not found, open configuration dialog.")
161            # Configuration dialog to setup setting file
162            dialog = dialog_startup.DialogStartup()
163            dialog.exec_()
164
165            # checks if the cancel button was pressed
166            if dialog_startup.global_var_terminate_app == 1:
167                os.remove(constants.SETTINGS_FULL_FILEPATH)
168                constants.PYSSA_LOGGER.info("Configuration dialog closed, and removed new settings file.")
169                sys.exit()
170
171            self._application_settings.app_launch = 1
172            self._application_settings.workspace_path = pathlib.Path(dialog_startup.global_var_startup_workspace)
173
174            constants.PYSSA_LOGGER.info("Demo projects are getting downloaded and extracted ...")
175            import zipfile
176
177            with zipfile.ZipFile(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"), "r") as zip_ref:
178                zip_ref.extractall(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects"))
179            constants.PYSSA_LOGGER.info(
180                "Demo projects are downloaded and extracted.\n Import of demo projects started ...",
181            )
182
183            path_of_demo_projects = pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects")
184            tmp_project = project.Project("", dialog_startup.global_var_startup_workspace)
185            for tmp_filename in os.listdir(path_of_demo_projects):
186                try:
187                    tmp_project = tmp_project.deserialize_project(
188                        pathlib.Path(f"{path_of_demo_projects}/{tmp_filename}"),
189                        self._application_settings,
190                    )
191                except exception.IllegalArgumentError:
192                    constants.PYSSA_LOGGER.warning(
193                        "The workspace path does not exist on this system, " "but this is due to the demo projects.",
194                    )
195                tmp_project.set_workspace_path(dialog_startup.global_var_startup_workspace)
196                new_filepath = pathlib.Path(f"{dialog_startup.global_var_startup_workspace}/{tmp_filename}")
197                tmp_project.serialize_project(new_filepath)
198            constants.PYSSA_LOGGER.info("Import process of demo projects finished.")
199            try:
200                os.remove(pathlib.Path(f"{constants.SETTINGS_DIR}/demo-projects.zip"))
201            except FileNotFoundError:
202                constants.PYSSA_LOGGER.warning("Zip archive of demo projects could not be found!")
203            constants.PYSSA_LOGGER.info("Serialize settings ...")
204            self._application_settings.serialize_settings()
205            constants.PYSSA_LOGGER.info("Serialize settings finished.")
206
207            QtWidgets.QApplication.restoreOverrideCursor()
208
209        globals.g_settings = main_window_util.setup_app_settings(self._application_settings)
210        self._application_settings = globals.g_settings
211        # </editor-fold>
212        # Check version number
213        main_window_util.check_version_number()
214
215        # <editor-fold desc="Class attributes">
216        self._workspace_path = self._application_settings.workspace_path
217        self._workspace_status = f"Current workspace: {str(self._workspace_path)}"
218        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
219        self.prediction_configuration = prediction_configuration.PredictionConfiguration(True, "pdb70")
220        self.results_name = ""
221        self.no_of_selected_chains = 0
222        self.plot_dialog = QtWidgets.QDialog(self._view)
223        self.view_box = None
224        self.block_box_expert_install = basic_boxes.no_buttons(
225            "Local Colabfold installation",
226            "An installation process is currently running.",
227            QtWidgets.QMessageBox.Information,
228        )
229        self.prediction_type = 0
230        self.current_session = current_session.CurrentSession("", "", "")
231        self.is_distance_plot_open = False
232        self.distance_plot_dialog = None
233
234        self.main_window_state = main_window_state.MainWindowState(
235            results_state.ResultsState(),
236            image_state.ImageState(),
237        )
238
239        constants.PYSSA_LOGGER.info("Setup class attributes finished.")
240        # </editor-fold>
241
242        # sets up the status bar
243        self._setup_statusbar()
244        tools.create_directory(constants.SETTINGS_DIR, "scratch")
245        self._setup_default_configuration()
246
247        # if len(os.listdir(constants.LOG_PATH)) > 0:
248        #     self.open_change_log()
249
250        constants.PYSSA_LOGGER.info("Setup rest of GUI related elements ...")
251
252        # <editor-fold desc="GUI page management">
253        # -- Gui page management vars
254        self.batch_analysis_management: gui_page_management.GuiPageManagement
255        self.results_management: gui_page_management.GuiPageManagement
256
257        # management functions
258        self._create_batch_analysis_management()
259        self._create_results_management()
260
261        # </editor-fold>
262
263        # <editor-fold desc="Block box definitions">
264        self.block_box_analysis = basic_boxes.no_buttons(
265            "Analysis",
266            "An analysis is currently running, please wait.",
267            QtWidgets.QMessageBox.Information,
268        )
269        self.block_box_prediction: QtWidgets.QMessageBox = QtWidgets.QMessageBox()
270        self.block_box_images = basic_boxes.no_buttons(
271            "Analysis Images",
272            "Images getting created, please wait.",
273            QtWidgets.QMessageBox.Information,
274        )
275        self.block_box_uni = basic_boxes.no_buttons("Generic", "Generic", QtWidgets.QMessageBox.Information)
276
277        # </editor-fold>
278
279        # configure gui element properties
280        self._view.ui.txt_results_aligned_residues.setAlignment(QtCore.Qt.AlignRight)
281        self._view.ui.table_pred_mono_prot_to_predict.setSizeAdjustPolicy(
282            QtWidgets.QAbstractScrollArea.AdjustToContents,
283        )
284        self._view.ui.table_pred_mono_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
285        self._view.ui.table_pred_multi_prot_to_predict.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft)
286        self._view.ui.list_pred_analysis_multi_ref_chains.setSelectionMode(
287            QtWidgets.QAbstractItemView.ExtendedSelection,
288        )
289        self._view.ui.list_pred_analysis_multi_model_chains.setSelectionMode(
290            QtWidgets.QAbstractItemView.ExtendedSelection,
291        )
292
293        # helper attributes
294        self.pymol_session_specs = {
295            pyssa_keys.SESSION_SPEC_PROTEIN: [0, ""],
296            pyssa_keys.SESSION_SPEC_COLOR: [0, ""],
297            pyssa_keys.SESSION_SPEC_REPRESENTATION: [0, ""],
298            pyssa_keys.SESSION_SPEC_BG_COLOR: [0, ""],
299        }
300
301        # <editor-fold desc="Setup defaults for pages">
302        self._init_fill_combo_boxes()
303        self._init_new_page()
304        self._init_use_page()
305        self._init_local_pred_mono_page()
306        self._init_local_pred_multi_page()
307        self._init_batch_analysis_page()
308        self._view.ui.action_toggle_notebook_visibility.setVisible(False)
309        self._view.ui.action_settings_model_w_off_colab_notebook.setVisible(False)
310        self.last_sidebar_button = QtWidgets.QPushButton()
311        self._view.ui.table_pred_mono_prot_to_predict.setEditTriggers(
312            self._view.ui.table_pred_mono_prot_to_predict.NoEditTriggers,
313        )
314        self._view.ui.table_pred_multi_prot_to_predict.setEditTriggers(
315            self._view.ui.table_pred_multi_prot_to_predict.NoEditTriggers,
316        )
317        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEditTriggers(
318            self._view.ui.table_pred_analysis_mono_prot_to_predict.NoEditTriggers,
319        )
320        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEditTriggers(
321            self._view.ui.table_pred_analysis_multi_prot_to_predict.NoEditTriggers,
322        )
323
324        # TODO: temp gui changes (need to be changed in the designer)
325        self._view.ui.lbl_hotspots_resi_show.setText("Residue(s) as sticks")
326        self._view.ui.lbl_hotspots_resi_hide.setText("Residue(s) as sticks")
327
328        # fixme: should the pdf documentation be accessible through the pyssa gui?
329        self._view.ui.action_help_docs_pdf.setText("Documentation")
330        self._view.ui.action_help_docs_pdf.setVisible(True)
331        self._view.ui.action_help_docs.setText("Tutorials")
332        self._view.ui.action_help_docs.setVisible(True)
333
334        if self._application_settings.wsl_install == 1 and self._application_settings.local_colabfold == 0:
335            self._view.ui.action_install_from_file.setVisible(True)
336        else:
337            self._view.ui.action_install_from_file.setVisible(False)
338        # </editor-fold>
339
340        self._connect_all_gui_elements()
341
342        self._project_watcher.show_valid_options(self._view.ui)
343        self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
344
345        self.threadpool = QtCore.QThreadPool()
346        # create scratch and cache dir
347        try:
348            filesystem_helpers.delete_directory(constants.SCRATCH_DIR)
349        except Exception as e:
350            constants.PYSSA_LOGGER.warning(f"Scratch path could not be deleted. {e}")
351        filesystem_helpers.create_directory(constants.SCRATCH_DIR)
352        filesystem_helpers.create_directory(constants.CACHE_DIR)

Constructor.

Arguments:
  • a_view: the main view of the pyssa plugin.
Raises:
  • IllegalArgumentException: If an argument is illegal.
prediction_configuration
results_name
no_of_selected_chains
plot_dialog
view_box
block_box_expert_install
prediction_type
current_session
is_distance_plot_open
distance_plot_dialog
main_window_state
batch_analysis_management: pyssa.util.gui_page_management.GuiPageManagement
results_management: pyssa.util.gui_page_management.GuiPageManagement
block_box_analysis
block_box_prediction: PyQt5.QtWidgets.QMessageBox
block_box_images
block_box_uni
pymol_session_specs
last_sidebar_button
threadpool
def start_worker_thread(self, worker_obj: object, post_process_func) -> None:
354    def start_worker_thread(self, worker_obj: object, post_process_func) -> None:  # noqa: ANN001
355        """Sets up the worker, moves the worker to a thread and starts the thread.
356
357        Args:
358            worker_obj: an object of type <work>Worker (QObject).
359            post_process_func: a function which sould be executed if the worker is finished.
360        """
361        self.tmp_thread = QtCore.QThread()
362        self.tmp_worker = worker_obj
363        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, post_process_func)
364        self.tmp_thread.start()

Sets up the worker, moves the worker to a thread and starts the thread.

Arguments:
  • worker_obj: an object of type Worker (QObject).
  • post_process_func: a function which sould be executed if the worker is finished.
def restore_settings(self) -> None:
782    def restore_settings(self) -> None:
783        """Restores the settings.xml file to the default values."""
784        out = gui_utils.warning_dialog_restore_settings("Are you sure you want to restore all settings?")
785        if out:
786            tools.restore_default_settings(self._application_settings)
787            self._view.status_bar.showMessage("Settings were successfully restored.")
788            logging.info("Settings were successfully restored.")
789        else:
790            self._view.status_bar.showMessage("Settings were not modified.")
791            logging.info("Settings were not modified.")

Restores the settings.xml file to the default values.

def quit_app(self) -> None:
793    def quit_app(self) -> None:
794        """Closes the entire plugin."""
795        self._view.quit_app()

Closes the entire plugin.

@staticmethod
def clear_all_log_files() -> None:
797    @staticmethod
798    def clear_all_log_files() -> None:
799        """Clears all log files generated under .pyssa/logs."""
800        response = basic_boxes.yes_or_no(
801            "Clear log files",
802            "Are you sure you want to delete all log files?",
803            QtWidgets.QMessageBox.Information,
804        )
805        if response:
806            try:
807                shutil.rmtree(str(constants.LOG_PATH))
808            except PermissionError:
809                print("The active log file was not deleted.")
810            if len(os.listdir(str(constants.LOG_PATH))) == 1:
811                basic_boxes.ok("Clear log files", "All log files could be deleted.", QtWidgets.QMessageBox.Information)
812                constants.PYSSA_LOGGER.info("All log files were deleted.")
813            else:
814                basic_boxes.ok("Clear log files", "Not all log files could be deleted.", QtWidgets.QMessageBox.Warning)
815                constants.PYSSA_LOGGER.warning("Not all log files were deleted!")

Clears all log files generated under .pyssa/logs.

def open_settings_global(self) -> None:
818    def open_settings_global(self) -> None:
819        """Opens the dialog for the global settings."""
820        dialog = dialog_settings_global.DialogSettingsGlobal()
821        dialog.exec_()
822        self._application_settings = self._application_settings.deserialize_settings()
823        globals.g_settings = self._application_settings
824        self._workspace_path = globals.g_settings.workspace_path
825        self._workspace_label = QtWidgets.QLabel(f"Current Workspace: {self._workspace_path}")
826        self._setup_statusbar()

Opens the dialog for the global settings.

def open_logs(self) -> None:
828    def open_logs(self) -> None:
829        """Opens a file explorer with all log files and can open a log file in the default application."""
830        file_dialog = QtWidgets.QFileDialog()
831        log_path = str(constants.LOG_PATH)
832        file_dialog.setDirectory(log_path)
833        file_path, _ = file_dialog.getOpenFileName(self._view, "Select a log file to open", "", "LOG File (*.log)")
834        if file_path:
835            os.startfile(file_path)

Opens a file explorer with all log files and can open a log file in the default application.

@staticmethod
def open_tutorial() -> None:
837    @staticmethod
838    def open_tutorial() -> None:
839        """Opens the official tutorial pdf file."""
840        tmp_dialog = dialog_tutorial_videos.TutorialVideosDialog()
841        tmp_dialog.exec_()

Opens the official tutorial pdf file.

@staticmethod
def open_documentation() -> None:
843    @staticmethod
844    def open_documentation() -> None:
845        """Opens the official plugin documentation as PDF."""
846        os.startfile(constants.DOCS_PATH)

Opens the official plugin documentation as PDF.

@staticmethod
def open_about() -> None:
848    @staticmethod
849    def open_about() -> None:
850        """Opens the About dialog."""
851        dialog = dialog_about.DialogAbout()
852        dialog.exec_()

Opens the About dialog.

def open_page_information(self) -> None:
854    def open_page_information(self) -> None:
855        """Opens the message box, to display extra information based on the page."""
856        with open(
857            f"{constants.PAGE_HELP_PATHS_DICT[self._view.ui.lbl_page_title.text()]}",
858            "r",
859            encoding="utf-8",
860        ) as file:
861            html_content = file.read()
862            file.close()
863        tmp_dialog = dialog_help.DialogHelp(html_content)
864        tmp_dialog.exec_()

Opens the message box, to display extra information based on the page.

@staticmethod
def open_release_notes_in_standard_application() -> None:
866    @staticmethod
867    def open_release_notes_in_standard_application() -> None:
868        """Opens the release notes in the default app."""
869        os.startfile(constants.CHANGELOG_HTML_PATH)

Opens the release notes in the default app.

def create_new_project(self) -> None:
927    def create_new_project(self) -> None:
928        """Creates a new project with the content of the new page."""
929        # <editor-fold desc="Checks">
930        if self._application_settings.wsl_install == 0:
931            basic_boxes.ok(
932                "Create new project",
933                "Please install local colabfold to create a project!",
934                QtWidgets.QMessageBox.Warning,
935            )
936            return
937        if self._application_settings.local_colabfold == 0:
938            basic_boxes.ok(
939                "Create new project",
940                "Please install local colabfold to create a project!",
941                QtWidgets.QMessageBox.Warning,
942            )
943            return
944
945        # </editor-fold>
946
947        self._view.wait_spinner.start()
948        an_add_protein_flag: bool = False
949        if self._view.ui.cb_new_add_reference.checkState() == 2:
950            an_add_protein_flag = True
951
952        self._active_task = tasks.Task(
953            target=main_presenter_async.create_new_project,
954            args=(
955                self._view.ui.txt_new_project_name.text(),
956                self._workspace_path,
957                an_add_protein_flag,
958                self._view.ui.txt_new_choose_reference.text(),
959            ),
960            post_func=self.__await_create_new_project,
961        )
962        self._active_task.start()
963        self.update_status("Creating new project ...")

Creates a new project with the content of the new page.

def open_project(self) -> None:
 988    def open_project(self) -> None:
 989        """Initiates the task to open an existing project."""
 990        self._view.wait_spinner.start()
 991        self._active_task = tasks.Task(
 992            target=main_presenter_async.open_project,
 993            args=(
 994                self._workspace_path,
 995                self._view.ui.txt_open_selected_project.text(),
 996                self._application_settings,
 997            ),
 998            post_func=self.__await_open_project,
 999        )
1000        self._active_task.start()
1001        self.update_status("Opening existing project ...")

Initiates the task to open an existing project.

def delete_project(self) -> None:
1025    def delete_project(self) -> None:
1026        """Deletes an existing project."""
1027        # popup message which warns the user that the selected project gets deleted
1028        response: bool = gui_utils.warning_message_project_gets_deleted()
1029        tmp_project_name = self._view.ui.txt_delete_selected_projects.text()
1030        if response is True:
1031            os.remove(pathlib.Path(f"{self._workspace_path}/{self._view.ui.txt_delete_selected_projects.text()}"))
1032            if self._view.ui.txt_delete_selected_projects.text() == self._view.ui.lbl_current_project_name.text():
1033                self._view.ui.lbl_current_project_name.clear()
1034            self._view.ui.txt_delete_selected_projects.clear()
1035            # update list
1036            self._view.ui.list_delete_projects.clear()
1037            # pre-process
1038            self._view.status_bar.showMessage(self._workspace_label.text())
1039            self._view.ui.list_delete_projects.clear()
1040            self._view.status_bar.showMessage(self._workspace_label.text())
1041            tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
1042            constants.PYSSA_LOGGER.info(f"The project {tmp_project_name} was successfully deleted.")
1043            if self._view.ui.list_delete_projects.count() == 0:
1044                self.display_home_page()
1045                self._project_watcher.check_workspace_for_projects(self._workspace_path, self._view.ui)
1046        else:
1047            constants.PYSSA_LOGGER.info("No project has been deleted. No changes were made.")

Deletes an existing project.

def save_project(self) -> None:
1052    def save_project(self) -> None:
1053        """Saves the project.xml."""
1054        self._view.wait_spinner.start()
1055        self.last_sidebar_button = styles.color_sidebar_buttons(
1056            self.last_sidebar_button,
1057            self._view.ui.btn_save_project,
1058        )
1059        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1060        self._active_task = tasks.Task(
1061            target=main_presenter_async.save_project,
1062            args=(self._current_project, 0),
1063            post_func=self.__await_save_project,
1064        )
1065        self._active_task.start()
1066        self.update_status("Saving current project ...")

Saves the project.xml.

def check_for_cleaning(self) -> None:
1076    def check_for_cleaning(self) -> None:
1077        """Checks if the selected protein can be cleaned."""
1078        self._view.wait_spinner.start()
1079        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1080        try:
1081            tmp_protein_name: str = self._view.ui.list_edit_project_proteins.currentItem().text()
1082        except AttributeError:
1083            self._view.wait_spinner.stop()
1084            return
1085        self._active_task = tasks.Task(
1086            target=main_presenter_async.check_for_cleaning,
1087            args=(
1088                tmp_protein_name,
1089                self._current_project,
1090            ),
1091            post_func=self.__await_check_for_cleaning,
1092        )
1093        self._active_task.start()
1094        self.update_status("Checking protein properties ...")

Checks if the selected protein can be cleaned.

def clean_protein_new(self) -> None:
1138    def clean_protein_new(self) -> None:
1139        """Cleans the selected protein structure and creates a new cleaned structure."""
1140        self._view.wait_spinner.start()
1141        self._active_task = tasks.Task(
1142            target=main_presenter_async.clean_protein_new,
1143            args=(
1144                self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1145                self._current_project,
1146            ),
1147            post_func=self.__await_clean_protein_new,
1148        )
1149        self._active_task.start()
1150        self.update_status("Duplicating and cleaning protein ...")

Cleans the selected protein structure and creates a new cleaned structure.

def clean_protein_update(self) -> None:
1158    def clean_protein_update(self) -> None:
1159        """Cleans the selected protein structure."""
1160        self._view.wait_spinner.start()
1161        if basic_boxes.yes_or_no(
1162            "Clean protein",
1163            "Are you sure you want to clean this protein?\n" "This will remove all organic and solvent components!",
1164            QtWidgets.QMessageBox.Information,
1165        ):
1166            self._active_task = tasks.Task(
1167                target=main_presenter_async.clean_protein_update,
1168                args=(
1169                    self._view.ui.list_edit_project_proteins.currentItem().text().replace(".pdb", ""),
1170                    self._current_project,
1171                ),
1172                post_func=self.__await_clean_protein_update,
1173            )
1174            self._active_task.start()
1175            self.update_status("Cleaning protein ...")
1176        else:
1177            constants.PYSSA_LOGGER.info("No protein has been cleaned.")
1178            self._view.wait_spinner.stop()

Cleans the selected protein structure.

def delete_protein(self) -> None:
1186    def delete_protein(self) -> None:
1187        """Deletes the selected protein structure."""
1188        self._view.wait_spinner.start()
1189        if gui_utils.warning_message_protein_gets_deleted():
1190            self._active_task = tasks.Task(
1191                target=main_presenter_async.delete_protein,
1192                args=(
1193                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1194                    self._current_project,
1195                ),
1196                post_func=self.__await_delete_protein,
1197            )
1198            self._active_task.start()
1199            self.update_status("Deleting protein ...")
1200        else:
1201            constants.PYSSA_LOGGER.info("No protein was deleted.")
1202            self._view.wait_spinner.stop()

Deletes the selected protein structure.

def add_existing_protein(self) -> None:
1210    def add_existing_protein(self) -> None:
1211        """Opens a dialog to adds an existing protein structure to the project."""
1212        self.tmp_dialog = view_add_protein.AddProteinView()
1213        self.tmp_dialog.return_value.connect(self.post_add_existing_protein)
1214        self.tmp_dialog.show()

Opens a dialog to adds an existing protein structure to the project.

def post_add_existing_protein(self, return_value: tuple) -> None:
1216    def post_add_existing_protein(self, return_value: tuple) -> None:
1217        """Adds an existing protein structure to the current project either by id or from the filesystem.
1218
1219        Args:
1220            return_value: a tuple consisting of the filepath or PDB id and the length of the first one.
1221        """
1222        self._view.wait_spinner.start()
1223        if return_value[1] > 0:
1224            self._active_task = tasks.Task(
1225                target=main_presenter_async.add_existing_protein_to_project,
1226                args=(return_value, self._current_project),
1227                post_func=self.__await_post_add_existing_protein,
1228            )
1229            self._active_task.start()
1230            self.update_status("Adding protein to current project ...")
1231        else:
1232            self._view.wait_spinner.stop()
1233            self.display_edit_page()

Adds an existing protein structure to the current project either by id or from the filesystem.

Arguments:
  • return_value: a tuple consisting of the filepath or PDB id and the length of the first one.
def save_selected_protein_structure_as_pdb_file(self) -> None:
1242    def save_selected_protein_structure_as_pdb_file(self) -> None:
1243        """Saves selected protein as pdb file."""
1244        self._view.wait_spinner.start()
1245        file_dialog = QtWidgets.QFileDialog()
1246        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1247        file_dialog.setDirectory(desktop_path)
1248        file_path, _ = file_dialog.getSaveFileName(
1249            self._view,
1250            "Save protein structure",
1251            "",
1252            "Protein Data Bank File (*.pdb)",
1253        )
1254        if file_path:
1255            self._active_task = tasks.Task(
1256                target=main_presenter_async.save_selected_protein_structure_as_pdb_file,
1257                args=(self._view.ui.list_edit_project_proteins.currentItem().text(), self._current_project, file_path),
1258                post_func=self.__await_save_selected_protein_structure_as_pdb_file,
1259            )
1260            self._active_task.start()
1261        else:
1262            self._view.wait_spinner.stop()

Saves selected protein as pdb file.

def rename_selected_protein_structure(self) -> None:
1287    def rename_selected_protein_structure(self) -> None:
1288        """Opens a new view to rename the selected protein."""
1289        self._view.wait_spinner.start()
1290        self.tmp_dialog = dialog_rename_protein.DialogRenameProtein(self._workspace_path)
1291        self.tmp_dialog.return_value.connect(self.post_rename_selected_protein_structure)
1292        self.tmp_dialog.show()

Opens a new view to rename the selected protein.

def post_rename_selected_protein_structure(self, return_value: tuple) -> None:
1294    def post_rename_selected_protein_structure(self, return_value: tuple) -> None:
1295        """Renames a selected protein structure."""
1296        if return_value[1] is True:
1297            self._active_task = tasks.Task(
1298                target=main_presenter_async.rename_selected_protein_structure,
1299                args=(
1300                    self._view.ui.list_edit_project_proteins.currentItem().text(),
1301                    return_value[0],
1302                    self._current_project,
1303                ),
1304                post_func=self.__await_post_rename_selected_protein_structure,
1305            )
1306            self._active_task.start()
1307        else:
1308            self._view.wait_spinner.stop()

Renames a selected protein structure.

def view_structure(self) -> None:
1318    def view_structure(self) -> None:
1319        """Displays the structure of the selected protein in pymol."""
1320        protein_name = self._view.ui.list_view_project_proteins.currentItem().text()
1321        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1322        cmd.reinitialize()
1323        self._view.ui.btn_manage_session.show()
1324        try:
1325            self._current_project.search_protein(protein_name).load_protein_pymol_session()
1326            constants.PYSSA_LOGGER.info("Loaded PyMOL session of protein %s", protein_name)
1327        except pymol.CmdException:
1328            constants.PYSSA_LOGGER.error("Error while loading protein in PyMOL!")
1329            return
1330        self.current_session = current_session.CurrentSession(
1331            "protein",
1332            protein_name,
1333            self._current_project.search_protein(protein_name).pymol_session,
1334        )
1335        print(self.current_session)

Displays the structure of the selected protein in pymol.

def display_use_page(self) -> None:
1340    def display_use_page(self) -> None:
1341        """Displays the use project page."""
1342        self._view.wait_spinner.start()
1343        if self.is_distance_plot_open:
1344            self.distance_plot_dialog.close()
1345            self.is_distance_plot_open = False
1346
1347        self.start_worker_thread(
1348            task_workers.LoadUsePageWorker(
1349                self._workspace_path,
1350                self._current_project.convert_list_of_proteins_to_list_of_protein_infos(),
1351            ),
1352            self.post_display_use_page,
1353        )
1354        self._init_use_page()

Displays the use project page.

def post_display_use_page(self, return_value) -> None:
1356    def post_display_use_page(self, return_value) -> None:  # noqa: ANN001
1357        """Displays the use project page, after cpu intense task (post thread method).
1358
1359        Args:
1360            return_value: the value which gets returned from the thread process
1361        """
1362        # this for-loop is necessary for eliminating all proteins which are in the current project from the ones which
1363        # are available
1364        for tmp_item in return_value[0]:
1365            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1366        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1367            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1368            tmp_prot_name = self._view.ui.list_use_selected_protein_structures.currentItem().text()
1369            if tmp_prot_name in return_value[1]:
1370                return_value[1].remove(tmp_prot_name)
1371
1372        for tmp_item in return_value[1]:
1373            self._view.ui.list_use_available_protein_structures.addItem(tmp_item)
1374        for tmp_project_name in return_value[2]:
1375            self._view.ui.list_use_existing_projects.addItem(QtWidgets.QListWidgetItem(tmp_project_name))
1376
1377        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 14, "Use existing project")
1378        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_use_page)
1379        self._view.wait_spinner.stop()

Displays the use project page, after cpu intense task (post thread method).

Arguments:
  • return_value: the value which gets returned from the thread process
def pre_create_use_project(self) -> None:
1381    def pre_create_use_project(self) -> None:
1382        """Sets up the worker for the create_use_project task."""
1383        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
1384        # copy proteins in new project
1385        proteins_to_copy = []
1386        for i in range(self._view.ui.list_use_selected_protein_structures.count()):
1387            self._view.ui.list_use_selected_protein_structures.setCurrentRow(i)
1388            proteins_to_copy.append(self._view.ui.list_use_selected_protein_structures.currentItem().text())
1389
1390        # <editor-fold desc="Worker setup">
1391        # --Begin: worker setup
1392        self.tmp_thread = QtCore.QThread()
1393        self.tmp_worker = task_workers.CreateUseProjectWorker(self._workspace_path, proteins_to_copy)
1394        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.create_use_project)
1395        self.tmp_thread.start()
1396        # --End: worker setup
1397
1398        # </editor-fold>
1399
1400        self._view.ui.lbl_current_project_name.setText(self._view.ui.txt_use_project_name.text())
1401        self._view.status_bar.showMessage(f"Creating new project: {self._view.ui.txt_use_project_name.text()} ...")
1402        # save project folder in current workspace
1403        new_project = project.Project(self._view.ui.txt_use_project_name.text(), self._workspace_path)
1404        # new_project.create_project_tree()
1405        self._current_project = new_project

Sets up the worker for the create_use_project task.

def create_use_project(self, proteins_for_new_project) -> None:
1407    def create_use_project(self, proteins_for_new_project) -> None:  # noqa: ANN001
1408        """Post thread method.
1409
1410        Args:
1411            proteins_for_new_project (list): the proteins which are in the new project
1412        """
1413        for tmp_protein_obj in proteins_for_new_project:
1414            self._current_project.add_existing_protein(tmp_protein_obj)
1415        self._current_project.serialize_project(
1416            pathlib.Path(f"{self._workspace_path}/{self._current_project.get_project_name()}.xml"),
1417        )
1418        # shows options which can be done with the data in the project folder
1419        self._project_watcher.current_project = self._current_project
1420        self._project_watcher.on_home_page = False
1421        self._project_watcher.show_valid_options(self._view.ui)
1422        self.project_scanner.project = self._current_project
1423        self._init_use_page()
1424        constants.PYSSA_LOGGER.info(
1425            f"The project {self._current_project.get_project_name()} was successfully created through a use.",
1426        )
1427        self.display_view_page()
1428        QtWidgets.QApplication.restoreOverrideCursor()

Post thread method.

Arguments:
  • proteins_for_new_project (list): the proteins which are in the new project
def import_project(self) -> None:
1433    def import_project(self) -> None:
1434        """Imports a project.xml into the current workspace."""
1435        self.last_sidebar_button = styles.color_sidebar_buttons(
1436            self.last_sidebar_button,
1437            self._view.ui.btn_import_project,
1438        )
1439        file_dialog = QtWidgets.QFileDialog()
1440        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1441        file_dialog.setDirectory(desktop_path)
1442        file_path, _ = file_dialog.getOpenFileName(
1443            self._view,
1444            "Select a project file to import",
1445            "",
1446            "XML Files (*.xml)",
1447        )
1448        if file_path:
1449            tmp_project = project.Project("", self._workspace_path)
1450            tmp_project = tmp_project.deserialize_project(pathlib.Path(file_path), self._application_settings)
1451            tmp_project.set_workspace_path(self._workspace_path)
1452            if len(tmp_project.proteins) <= 1:
1453                if self._application_settings.wsl_install == 0:
1454                    basic_boxes.ok(
1455                        "Create new project",
1456                        "Please install local colabfold to import this project!",
1457                        QtWidgets.QMessageBox.Warning,
1458                    )
1459                    return
1460                elif self._application_settings.local_colabfold == 0:  # noqa: RET505
1461                    basic_boxes.ok(
1462                        "Create new project",
1463                        "Please install local colabfold to import this project!",
1464                        QtWidgets.QMessageBox.Warning,
1465                    )
1466                    return
1467            new_filepath = pathlib.Path(f"{self._workspace_path}/{tmp_project.get_project_name()}.xml")
1468            tmp_project.serialize_project(new_filepath)
1469            self._current_project = self._current_project.deserialize_project(new_filepath, self._application_settings)
1470            constants.PYSSA_LOGGER.info(f"Opening the project {self._current_project.get_project_name()}.")
1471            self._project_watcher.current_project = self._current_project
1472            self.project_scanner.project = self._current_project
1473            constants.PYSSA_LOGGER.info(
1474                f"{self._project_watcher.current_project.get_project_name()} is the current project.",
1475            )
1476            self._view.ui.lbl_current_project_name.setText(self._current_project.get_project_name())
1477            self._project_watcher.on_home_page = False
1478            self._project_watcher.show_valid_options(self._view.ui)
1479            self._view.ui.btn_manage_session.show()
1480            self.display_view_page()
1481            basic_boxes.ok(
1482                "Import Project",
1483                "The project was successfully imported.",
1484                QtWidgets.QMessageBox.Information,
1485            )

Imports a project.xml into the current workspace.

def export_current_project(self) -> None:
1487    def export_current_project(self) -> None:
1488        """Exports the current project to an importable format."""
1489        if self.is_distance_plot_open:
1490            self.distance_plot_dialog.close()
1491            self.is_distance_plot_open = False
1492        self.last_sidebar_button = styles.color_sidebar_buttons(
1493            self.last_sidebar_button,
1494            self._view.ui.btn_export_project,
1495        )
1496        file_dialog = QtWidgets.QFileDialog()
1497        desktop_path = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DesktopLocation)[0]
1498        file_dialog.setDirectory(desktop_path)
1499        file_path, _ = file_dialog.getSaveFileName(self._view, "Save current project", "", "XML Files (*.xml)")
1500        if file_path:
1501            self._current_project.serialize_project(pathlib.Path(file_path))
1502            basic_boxes.ok(
1503                "Export Project",
1504                "The project was successfully exported.",
1505                QtWidgets.QMessageBox.Information,
1506            )

Exports the current project to an importable format.

def close_project(self) -> None:
1511    def close_project(self) -> None:
1512        """Closes the current project."""
1513        if self.is_distance_plot_open:
1514            self.distance_plot_dialog.close()
1515            self.is_distance_plot_open = False
1516        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
1517        cmd.reinitialize()
1518        self._view.ui.list_hotspots_choose_protein.clear()
1519        self._project_watcher.on_home_page = True
1520        self._project_watcher.current_project = project.Project("", pathlib.Path(""))
1521        self._project_watcher.show_valid_options(self._view.ui)
1522        self._view.ui.lbl_current_project_name.setText("")
1523        self._init_all_pages()
1524        self.results_name = ""
1525        constants.PYSSA_LOGGER.info(f"The project {self._current_project.get_project_name()} was closed")
1526        self.display_home_page()

Closes the current project.

def post_predict_esm_monomer(self, output) -> None:
1531    def post_predict_esm_monomer(self, output) -> None:  # noqa: ANN001
1532        """Post thread method, for the prediction process.
1533
1534        Args:
1535            output (list): the proteins which got predicted
1536        """
1537        self.block_box_prediction.destroy(True)
1538        for tmp_filename in os.listdir(constants.ESMFOLD_PDB_DIR):
1539            constants.PYSSA_LOGGER.info(
1540                f"Add protein {tmp_filename} to the current project {self._current_project.get_project_name()}",
1541            )
1542            self._current_project.add_existing_protein(
1543                protein.Protein(
1544                    tmp_filename.replace(".pdb", ""),
1545                    path_util.FilePath(pathlib.Path(f"{constants.ESMFOLD_PDB_DIR}/{tmp_filename}")),
1546                ),
1547            )
1548        if len(output) > 0:
1549            formatted_output = ", ".join(output)
1550            basic_boxes.ok(
1551                "ESMFold Prediction",
1552                f"These protein prediction failed: {formatted_output}.",
1553                QtWidgets.QMessageBox.Critical,
1554            )
1555        else:
1556            basic_boxes.ok("ESMFold Prediction", "The prediction was successful.", QtWidgets.QMessageBox.Information)
1557        self._current_project.serialize_project(self._current_project.get_project_xml_path())
1558        self.display_view_page()
1559        self._project_watcher.show_valid_options(self._view.ui)

Post thread method, for the prediction process.

Arguments:
  • output (list): the proteins which got predicted
def predict_esm_monomer(self) -> None:
1561    def predict_esm_monomer(self) -> None:
1562        """Sets up the worker to predict the proteins with the ESM-Fold."""
1563        # <editor-fold desc="Worker setup">
1564        # --Begin: worker setup
1565        self.tmp_thread = QtCore.QThread()
1566        self.tmp_worker = task_workers.EsmFoldWorker(self._view.ui.table_esm_prot_to_predict)
1567        self.tmp_thread = task_workers.setup_worker_for_work(
1568            self.tmp_thread,
1569            self.tmp_worker,
1570            self.post_predict_esm_monomer,
1571        )
1572        self.tmp_thread.start()
1573        # --End: worker setup
1574
1575        # </editor-fold>
1576
1577        self.block_box_prediction = QtWidgets.QMessageBox()
1578        self.block_box_prediction = gui_utils.setup_standard_block_box(
1579            self.block_box_prediction,
1580            "Structure Prediction",
1581            "A prediction is currently running.",
1582        )
1583        # self.block_box_prediction.setStandardButtons(QtWidgets.QMessageBox.NoButton)
1584        # self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1585        # self.block_box_prediction.setWindowIcon(
1586        #     PyQt5.constants.PLUGIN_LOGO_ICON_OBJ)
1587        # styles.set_stylesheet(self.block_box_prediction)
1588        # self.block_box_prediction.setWindowTitle("Structure Prediction")
1589        # self.block_box_prediction.setText("A prediction is currently running.")
1590        self.block_box_prediction.exec_()

Sets up the worker to predict the proteins with the ESM-Fold.

def post_prediction_process(self, an_exit_code: int, an_exit_code_description: str) -> None:
1595    def post_prediction_process(self, an_exit_code: int, an_exit_code_description: str) -> None:
1596        """Process which runs after each prediction job."""
1597        if an_exit_code == exit_codes.ERROR_WRITING_FASTA_FILES[0]:
1598            self.block_box_prediction.destroy(True)
1599            basic_boxes.ok(
1600                "Prediction",
1601                "Prediction failed because there was an error writing the fasta file(s)!",
1602                QtWidgets.QMessageBox.Critical,
1603            )
1604            self.display_view_page()
1605            self._project_watcher.show_valid_options(self._view.ui)
1606            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1607        elif an_exit_code == exit_codes.ERROR_FASTA_FILES_NOT_FOUND[0]:
1608            self.block_box_prediction.destroy(True)
1609            basic_boxes.ok(
1610                "Prediction",
1611                "Prediction failed because the fasta file(s) could not be found!",
1612                QtWidgets.QMessageBox.Critical,
1613            )
1614            self.display_view_page()
1615            self._project_watcher.show_valid_options(self._view.ui)
1616            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1617        elif an_exit_code == exit_codes.ERROR_PREDICTION_FAILED[0]:
1618            self.block_box_prediction.destroy(True)
1619            basic_boxes.ok(
1620                "Prediction",
1621                "Prediction failed because a subprocess failed!",
1622                QtWidgets.QMessageBox.Critical,
1623            )
1624            self.display_view_page()
1625            self._project_watcher.show_valid_options(self._view.ui)
1626            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1627        elif an_exit_code == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
1628            self.block_box_prediction.destroy(True)
1629            basic_boxes.ok(
1630                "Prediction",
1631                "Prediction failed because of an unknown error!",
1632                QtWidgets.QMessageBox.Critical,
1633            )
1634            self.display_view_page()
1635            self._project_watcher.show_valid_options(self._view.ui)
1636            constants.PYSSA_LOGGER.error(f"Prediction ended with exit code {an_exit_code}: {an_exit_code_description}")
1637        elif an_exit_code == exit_codes.EXIT_CODE_ZERO[0]:
1638            # Prediction was successful
1639            if self.prediction_type == constants.PREDICTION_TYPE_PRED:
1640                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1641                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1642                self.block_box_prediction.destroy(True)
1643                basic_boxes.ok(
1644                    "Structure prediction",
1645                    "All structure predictions are done. Go to View to check the new proteins.",
1646                    QtWidgets.QMessageBox.Information,
1647                )
1648                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1649                self._project_watcher.show_valid_options(self._view.ui)
1650                self._init_local_pred_mono_page()
1651                self._init_local_pred_multi_page()
1652                self.display_view_page()
1653            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS:
1654                # executes if monomers were successfully predicted
1655                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1656                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1657                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1658                constants.PYSSA_LOGGER.info("Begin analysis process.")
1659                constants.PYSSA_LOGGER.debug(
1660                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1661                )
1662
1663                # self.worker_analysis = workers.AnalysisWorkerPool(
1664                #    self._view.ui.list_pred_analysis_mono_overview, self._view.ui.cb_pred_analysis_mono_images,
1665                #    self._view.status_bar, self._current_project, self._application_settings, self._init_mono_pred_analysis_page)
1666                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1667                # self.threadpool.start(self.worker_analysis)
1668                constants.PYSSA_LOGGER.debug(
1669                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1670                )
1671
1672                # <editor-fold desc="Worker setup">
1673                # TODO: test code below
1674                # --Begin: worker setup
1675                self.tmp_thread = QtCore.QThread()
1676                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1677                    self._view.ui.list_pred_analysis_mono_overview,
1678                    self._view.ui.cb_pred_analysis_mono_images,
1679                    self._view.status_bar,
1680                    self._current_project,
1681                    self._application_settings,
1682                    self._init_mono_pred_analysis_page,
1683                )
1684                self.tmp_thread = task_workers.setup_worker_for_work(
1685                    self.tmp_thread,
1686                    self.tmp_worker,
1687                    self.display_view_page,
1688                )
1689                self.tmp_worker.finished.connect(self.post_analysis_process)
1690                self.tmp_thread.start()
1691                # --End: worker setup
1692
1693                # </editor-fold>
1694
1695                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1696                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1697                self.block_box_prediction.destroy(True)
1698                self.block_box_analysis.exec_()
1699                self.display_view_page()
1700                self._project_watcher.show_valid_options(self._view.ui)
1701            elif self.prediction_type == constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS:
1702                self._current_project.serialize_project(self._current_project.get_project_xml_path())
1703                constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
1704                constants.PYSSA_LOGGER.info("All structure predictions are done.")
1705                constants.PYSSA_LOGGER.info("Begin analysis process.")
1706                constants.PYSSA_LOGGER.debug(
1707                    f"Thread count before analysis worker: {self.threadpool.activeThreadCount()}",
1708                )
1709
1710                # self.worker_analysis = workers.AnalysisWorkerPool(
1711                #    self._view.ui.list_pred_analysis_multi_overview, self._view.ui.cb_pred_analysis_multi_images,
1712                #    self._view.status_bar, self._current_project, self._application_settings, self._init_multi_pred_analysis_page)
1713                constants.PYSSA_LOGGER.info("Thread started for analysis process.")
1714                # self.threadpool.start(self.worker_analysis)
1715                constants.PYSSA_LOGGER.debug(
1716                    f"Thread count after analysis worker: {self.threadpool.activeThreadCount()}",
1717                )
1718
1719                # <editor-fold desc="Worker setup">
1720                # TODO: test code below
1721                # --Begin: worker setup
1722                self.tmp_thread = QtCore.QThread()
1723                self.tmp_worker = task_workers.DistanceAnalysisWorker(
1724                    self._view.ui.list_pred_analysis_multi_overview,
1725                    self._view.ui.cb_pred_analysis_multi_images,
1726                    self._view.status_bar,
1727                    self._current_project,
1728                    self._application_settings,
1729                    self._init_multi_pred_analysis_page,
1730                )
1731                self.tmp_thread = task_workers.setup_worker_for_work(
1732                    self.tmp_thread,
1733                    self.tmp_worker,
1734                    self.display_view_page,
1735                )
1736                self.tmp_worker.finished.connect(self.post_analysis_process)
1737                self.tmp_thread.start()
1738                # --End: worker setup
1739
1740                # </editor-fold>
1741
1742                if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
1743                    os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
1744                self.block_box_prediction.destroy(True)
1745                self.block_box_analysis.exec_()
1746                self.display_view_page()
1747                self._project_watcher.show_valid_options(self._view.ui)
1748        try:
1749            shutil.rmtree(pathlib.Path(f"{constants.SCRATCH_DIR}/local_predictions"))
1750        except Exception as e:
1751            constants.PYSSA_LOGGER.warning(f"Local predictions scratch path could not be deleted. {e}")

Process which runs after each prediction job.

def predict_local_monomer(self) -> None:
1753    def predict_local_monomer(self) -> None:
1754        """Sets tup the worker for the prediction with the colabfold."""
1755        self._view.wait_spinner.start()
1756        self.prediction_type = constants.PREDICTION_TYPE_PRED
1757        constants.PYSSA_LOGGER.info("Begin prediction process.")
1758        self.update_status("Begin prediction process ...")
1759        predictions: list[
1760            prediction_protein_info.PredictionProteinInfo
1761        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_mono_prot_to_predict)
1762
1763        self._active_task = tasks.Task(
1764            target=main_presenter_async.predict_protein_with_colabfold,
1765            args=(
1766                predictions,
1767                self.prediction_configuration,
1768                self._current_project,
1769            ),
1770            post_func=self.__await_predict_protein_with_colabfold,
1771        )
1772        self._active_task.start()
1773
1774        self.block_box_prediction = QtWidgets.QMessageBox()
1775        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1776        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1777        styles.set_stylesheet(self.block_box_prediction)
1778        self.block_box_prediction.setWindowTitle("Structure Prediction")
1779        self.block_box_prediction.setText("A prediction is currently running.")
1780        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1781        self.block_box_prediction.exec_()
1782        if self.block_box_prediction.clickedButton() == btn_abort:
1783            self.abort_prediction()
1784            self.block_box_prediction.close()
1785            self._view.wait_spinner.stop()
1786            return
1787        else:  # noqa: RET505
1788            self.block_box_prediction.close()
1789            self._view.wait_spinner.stop()

Sets tup the worker for the prediction with the colabfold.

def abort_prediction(self) -> None:
1861    def abort_prediction(self) -> None:
1862        """Aborts the running prediction."""
1863        constants.PYSSA_LOGGER.info("Structure prediction process was aborted manually.")
1864        subprocess.run(["wsl", "--shutdown"])
1865        constants.PYSSA_LOGGER.info("Shutdown of wsl environment.")
1866        filesystem_io.FilesystemCleaner.clean_prediction_scratch_folder()
1867        constants.PYSSA_LOGGER.info("Cleaned scratch directory.")
1868        basic_boxes.ok("Abort prediction", "The structure prediction was aborted.", QtWidgets.QMessageBox.Information)
1869        self.last_sidebar_button = styles.color_sidebar_buttons(
1870            self.last_sidebar_button,
1871            self._view.ui.btn_prediction_abort,
1872        )
1873        self._project_watcher.show_valid_options(self._view.ui)

Aborts the running prediction.

def predict_local_multimer(self) -> None:
1878    def predict_local_multimer(self) -> None:
1879        """Sets up the worker for the prediction with the colabfold."""
1880        self._view.wait_spinner.start()
1881        self.prediction_type = constants.PREDICTION_TYPE_PRED
1882        constants.PYSSA_LOGGER.info("Begin multimer prediction process.")
1883        self.update_status("Begin prediction process ...")
1884        predictions: list[
1885            prediction_protein_info.PredictionProteinInfo
1886        ] = prediction_util.get_prediction_name_and_seq_from_table(self._view.ui.table_pred_multi_prot_to_predict)
1887
1888        self._active_task = tasks.Task(
1889            target=main_presenter_async.predict_protein_with_colabfold,
1890            args=(
1891                predictions,
1892                self.prediction_configuration,
1893                self._current_project,
1894            ),
1895            post_func=self.__await_predict_protein_with_colabfold,
1896        )
1897        self._active_task.start()
1898
1899        self.block_box_prediction = QtWidgets.QMessageBox()
1900        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1901        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1902        styles.set_stylesheet(self.block_box_prediction)
1903        self.block_box_prediction.setWindowTitle("Structure Prediction")
1904        self.block_box_prediction.setText("A prediction is currently running.")
1905        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1906        self.block_box_prediction.exec_()
1907        if self.block_box_prediction.clickedButton() == btn_abort:
1908            self.abort_prediction()
1909            self.block_box_prediction.close()
1910            self._view.wait_spinner.stop()
1911        else:
1912            self.block_box_prediction.close()
1913            self._view.wait_spinner.stop()

Sets up the worker for the prediction with the colabfold.

def start_monomer_prediction_analysis(self) -> None:
1918    def start_monomer_prediction_analysis(self) -> None:
1919        """Sets up the worker for the prediction of the proteins."""
1920        self._view.wait_spinner.start()
1921        self.prediction_type = constants.PREDICTION_TYPE_PRED_MONO_ANALYSIS
1922        constants.PYSSA_LOGGER.info("Begin prediction process.")
1923        self.update_status("Begin prediction process ...")
1924        predictions: list[
1925            prediction_protein_info.PredictionProteinInfo
1926        ] = prediction_util.get_prediction_name_and_seq_from_table(
1927            self._view.ui.table_pred_analysis_mono_prot_to_predict,
1928        )
1929
1930        self._active_task = tasks.Task(
1931            target=main_presenter_async.predict_protein_with_colabfold,
1932            args=(
1933                predictions,
1934                self.prediction_configuration,
1935                self._current_project,
1936            ),
1937            post_func=self.__await_monomer_prediction_for_subsequent_analysis,
1938        )
1939        self._active_task.start()
1940
1941        self.block_box_prediction = QtWidgets.QMessageBox()
1942        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
1943        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
1944        styles.set_stylesheet(self.block_box_prediction)
1945        self.block_box_prediction.setWindowTitle("Structure Prediction")
1946        self.block_box_prediction.setText("A prediction is currently running.")
1947        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
1948        self.block_box_prediction.exec_()
1949        if self.block_box_prediction.clickedButton() == btn_abort:
1950            self.abort_prediction()
1951            self.block_box_prediction.close()
1952            self._view.wait_spinner.stop()
1953        else:
1954            self.block_box_prediction.close()
1955            self._view.wait_spinner.stop()

Sets up the worker for the prediction of the proteins.

def mono_pred_analysis_structure_analysis_next_2(self) -> None:
2042    def mono_pred_analysis_structure_analysis_next_2(self) -> None:
2043        """Shows the gui elements for the chain selection of protein 1."""
2044        self._view.wait_spinner.start()
2045        tmp_proteins_to_predict: list[str] = []
2046        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
2047            tmp_proteins_to_predict.append(
2048                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text(),
2049            )
2050        self._active_task = tasks.Task(
2051            target=main_presenter_async.check_chains_for_subsequent_analysis,
2052            args=(
2053                self._view.ui.box_pred_analysis_mono_prot_struct_1.currentText(),
2054                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
2055                self._current_project,
2056                tmp_proteins_to_predict,
2057            ),
2058            post_func=self.__await_mono_pred_analysis_structure_analysis_next_2,
2059        )
2060        self._active_task.start()

Shows the gui elements for the chain selection of protein 1.

def start_multimer_prediction_analysis(self) -> None:
2165    def start_multimer_prediction_analysis(self) -> None:
2166        """Sets up the prediction process."""
2167        self._view.wait_spinner.start()
2168        self.prediction_type = constants.PREDICTION_TYPE_PRED_MULTI_ANALYSIS
2169        constants.PYSSA_LOGGER.info("Begin prediction process.")
2170        self.update_status("Begin prediction process ...")
2171        predictions: list[
2172            prediction_protein_info.PredictionProteinInfo
2173        ] = prediction_util.get_prediction_name_and_seq_from_table(
2174            self._view.ui.table_pred_analysis_multi_prot_to_predict,
2175        )
2176
2177        self._active_task = tasks.Task(
2178            target=main_presenter_async.predict_protein_with_colabfold,
2179            args=(
2180                predictions,
2181                self.prediction_configuration,
2182                self._current_project,
2183            ),
2184            post_func=self.__await_multimer_prediction_for_subsequent_analysis,
2185        )
2186        self._active_task.start()
2187
2188        self.block_box_prediction = QtWidgets.QMessageBox()
2189        self.block_box_prediction.setIcon(QtWidgets.QMessageBox.Information)
2190        self.block_box_prediction.setWindowIcon(QtGui.QIcon(constants.PLUGIN_LOGO_FILEPATH))
2191        styles.set_stylesheet(self.block_box_prediction)
2192        self.block_box_prediction.setWindowTitle("Structure Prediction")
2193        self.block_box_prediction.setText("A prediction is currently running.")
2194        btn_abort = self.block_box_prediction.addButton("Abort", QtWidgets.QMessageBox.ActionRole)
2195        self.block_box_prediction.exec_()
2196        if self.block_box_prediction.clickedButton() == btn_abort:
2197            self.abort_prediction()
2198            self.block_box_prediction.close()
2199            self._view.wait_spinner.stop()
2200        else:
2201            self.block_box_prediction.close()
2202            self._view.wait_spinner.stop()

Sets up the prediction process.

def multi_pred_analysis_structure_analysis_next_2(self) -> None:
2288    def multi_pred_analysis_structure_analysis_next_2(self) -> None:
2289        """Shows the gui elements to select the chains in protein 1."""
2290        self._view.wait_spinner.start()
2291        tmp_proteins_to_predict: list[str] = []
2292        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
2293            tmp_proteins_to_predict.append(
2294                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text(),
2295            )
2296        self._active_task = tasks.Task(
2297            target=main_presenter_async.check_chains_for_subsequent_analysis,
2298            args=(
2299                self._view.ui.box_pred_analysis_multi_prot_struct_1.currentText(),
2300                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
2301                self._current_project,
2302                tmp_proteins_to_predict,
2303            ),
2304            post_func=self.__await_multi_pred_analysis_structure_analysis_next_2,
2305        )
2306        self._active_task.start()

Shows the gui elements to select the chains in protein 1.

def post_analysis_process(self, an_exit_code: tuple[int, str]) -> None:
2412    def post_analysis_process(self, an_exit_code: tuple[int, str]) -> None:
2413        """Post process after the analysis thread finished."""
2414        constants.PYSSA_LOGGER.debug("post_analysis_process() started ...")
2415        if an_exit_code[0] == exit_codes.ERROR_DISTANCE_ANALYSIS_FAILED[0]:
2416            self.block_box_analysis.destroy(True)
2417            basic_boxes.ok(
2418                "Distance analysis",
2419                "Distance analysis failed because there was an error during the analysis!",
2420                QtWidgets.QMessageBox.Critical,
2421            )
2422            constants.PYSSA_LOGGER.error(
2423                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2424            )
2425        elif an_exit_code[0] == exit_codes.EXIT_CODE_ONE_UNKNOWN_ERROR[0]:
2426            self.block_box_analysis.destroy(True)
2427            basic_boxes.ok(
2428                "Distance analysis",
2429                "Distance analysis failed because of an unknown error!",
2430                QtWidgets.QMessageBox.Critical,
2431            )
2432            constants.PYSSA_LOGGER.error(
2433                f"Distance analysis ended with exit code {an_exit_code[0]}: {an_exit_code[1]}",
2434            )
2435        elif an_exit_code[0] == exit_codes.EXIT_CODE_ZERO[0]:
2436            self._current_project.serialize_project(self._current_project.get_project_xml_path())
2437            constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2438            self.block_box_analysis.destroy(True)
2439            basic_boxes.ok(
2440                "Structure analysis",
2441                "All structure analysis' are done. Go to results to check the new results.",
2442                QtWidgets.QMessageBox.Information,
2443            )
2444            constants.PYSSA_LOGGER.info("All structure analysis' are done.")
2445
2446        self._project_watcher.show_valid_options(self._view.ui)
2447        self.display_view_page()
2448        self._init_batch_analysis_page()

Post process after the analysis thread finished.

def start_process_batch(self) -> None:
2450    def start_process_batch(self) -> None:
2451        """Sets up the worker for the analysis task."""
2452        constants.PYSSA_LOGGER.info("Begin analysis process.")
2453
2454        tmp_raw_analysis_run_names: list = []
2455        for row_no in range(self._view.ui.list_analysis_batch_overview.count()):
2456            tmp_raw_analysis_run_names.append(self._view.ui.list_analysis_batch_overview.item(row_no).text())
2457        self._active_task = tasks.Task(
2458            target=main_presenter_async.run_distance_analysis,
2459            args=(
2460                tmp_raw_analysis_run_names,
2461                self._current_project,
2462                self._application_settings,
2463                self._view.ui.cb_analysis_images.isChecked(),
2464            ),
2465            post_func=self.post_analysis_process,
2466        )
2467        self._active_task.start()
2468
2469        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2470            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2471
2472        self.block_box_analysis.exec_()
2473        self.display_view_page()

Sets up the worker for the analysis task.

def structure_analysis_next(self) -> None:
2475    def structure_analysis_next(self) -> None:
2476        """Shows the gui elements to select the chains in protein 1."""
2477        self._view.wait_spinner.start()
2478        self._active_task = tasks.Task(
2479            target=main_presenter_async.check_chains_for_analysis,
2480            args=(
2481                self._view.ui.box_analysis_batch_prot_struct_1.currentText(),
2482                self._view.ui.box_analysis_batch_prot_struct_2.currentText(),
2483                self._current_project,
2484            ),
2485            post_func=self.__await_structure_analysis_next,
2486        )
2487        self._active_task.start()

Shows the gui elements to select the chains in protein 1.

def post_image_creation_process(self) -> None:
2580    def post_image_creation_process(self) -> None:
2581        """Post method after the image creation task is finished."""
2582        self._current_project.serialize_project(self._current_project.get_project_xml_path())
2583        constants.PYSSA_LOGGER.info("Project has been saved to XML file.")
2584        self.block_box_images.destroy(True)
2585        basic_boxes.ok(
2586            "Analysis Images",
2587            "All images of all analysis' have been created. Go to results to check the new results.",
2588            QtWidgets.QMessageBox.Information,
2589        )
2590        constants.PYSSA_LOGGER.info("All images of all analysis' have been created.")
2591        self._init_analysis_image_page()
2592        self.display_view_page()
2593        self._project_watcher.show_valid_options(self._view.ui)

Post method after the image creation task is finished.

def start_automatic_image_creation(self) -> None:
2595    def start_automatic_image_creation(self) -> None:
2596        """Sets up the worker for the image creation process."""
2597        constants.PYSSA_LOGGER.info("Begin image creation process.")
2598        # self.worker_image_creation = workers.BatchImageWorkerPool(
2599        #    self._view.ui.list_analysis_images_struct_analysis, self._view.ui.list_analysis_images_creation_struct_analysis,
2600        #    self._view.status_bar, self._current_project)
2601        constants.PYSSA_LOGGER.info("Thread started for image creation process.")
2602        # self.threadpool.start(self.worker_image_creation)
2603
2604        # <editor-fold desc="Worker setup">
2605        # TODO: test code below
2606        # --Begin: worker setup
2607        self.tmp_thread = QtCore.QThread()
2608        self.tmp_worker = task_workers.BatchImageWorker(
2609            self._view.ui.list_analysis_images_struct_analysis,
2610            self._view.ui.list_analysis_images_creation_struct_analysis,
2611            self._view.status_bar,
2612            self._current_project,
2613        )
2614        self.tmp_thread = task_workers.setup_worker_for_work(self.tmp_thread, self.tmp_worker, self.display_view_page)
2615        self.tmp_worker.finished.connect(self.post_image_creation_process)
2616        self.tmp_thread.start()
2617        # --End: worker setup
2618
2619        # </editor-fold>
2620
2621        if not os.path.exists(constants.SCRATCH_DIR_ANALYSIS):
2622            os.mkdir(constants.SCRATCH_DIR_ANALYSIS)
2623
2624        self._view.ui.list_analysis_images_struct_analysis.setEnabled(False)
2625        self._view.ui.list_analysis_images_creation_struct_analysis.setEnabled(False)
2626
2627        # gui_elements_to_show = [
2628        #     self._view.ui.btn_analysis_abort,
2629        # ]
2630        # gui_elements_to_hide = [
2631        #     self._view.ui.btn_save_project,
2632        #     self._view.ui.btn_edit_page,
2633        #     self._view.ui.btn_view_page,
2634        #     self._view.ui.btn_use_page,
2635        #     self._view.ui.btn_export_project,
2636        #     self._view.ui.btn_close_project,
2637        #     self._view.ui.btn_batch_analysis_page,
2638        #     self._view.ui.btn_image_analysis_page,
2639        #     self._view.ui.btn_results_page,
2640        #     self._view.ui.lbl_handle_pymol_session,
2641        #     self._view.ui.btn_image_page,
2642        #     self._view.ui.btn_hotspots_page,
2643        # ]
2644        # gui_utils.manage_gui_visibility(gui_elements_to_show, gui_elements_to_hide)
2645
2646        self.block_box_images.exec_()

Sets up the worker for the image creation process.

def show_analysis_results_options(self) -> None:
2651    def show_analysis_results_options(self) -> None:
2652        """Shows the combo box of protein pairs."""
2653        self.results_management.show_stage_x(0)

Shows the combo box of protein pairs.

def show_results_interactions( self, gui_elements_to_show: list = None, gui_elements_to_hide: list = None) -> None:
2655    def show_results_interactions(self, gui_elements_to_show: list = None, gui_elements_to_hide: list = None) -> None:
2656        """Shows the gui elements of the results page.
2657
2658        Args:
2659            gui_elements_to_show: a list of gui elements which should get displayed.
2660            gui_elements_to_hide: a list of gui elements which should get hidden.
2661        """
2662        if gui_elements_to_hide is not None:
2663            self.results_management.show_gui_elements_stage_x(
2664                [0, 1],
2665                [],
2666                show_specific_elements=[
2667                    self._view.ui.lbl_results_analysis_options,
2668                    self._view.ui.cb_results_analysis_options,
2669                ],
2670                hide_specific_elements=gui_elements_to_hide,
2671            )
2672        else:
2673            self.results_management.show_gui_elements_stage_x(
2674                [0, 1],
2675                [],
2676                show_specific_elements=[
2677                    self._view.ui.lbl_results_analysis_options,
2678                    self._view.ui.cb_results_analysis_options,
2679                ],
2680            )

Shows the gui elements of the results page.

Arguments:
  • gui_elements_to_show: a list of gui elements which should get displayed.
  • gui_elements_to_hide: a list of gui elements which should get hidden.
def load_results(self) -> None:
2682    def load_results(self) -> None:
2683        """Sets up the worker for the result loading process."""
2684        self._view.wait_spinner.start()
2685        if self.is_distance_plot_open:
2686            self.distance_plot_dialog.close()
2687            self.is_distance_plot_open = False
2688        self.results_name = self._view.ui.cb_results_analysis_options.currentText()
2689        if self.results_name == "":
2690            self.show_analysis_results_options()
2691            self._view.wait_spinner.stop()
2692            return
2693        tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
2694
2695        self._active_task = tasks.Task(
2696            target=main_presenter_async.load_results,
2697            args=(
2698                self._current_project,
2699                self.results_name,
2700            ),
2701            post_func=self.__await_load_results,
2702        )
2703        self._active_task.start()
2704
2705        self._view.ui.list_results_interest_regions.clear()
2706        self._view.status_bar.showMessage(f"Loading results of {self.results_name} ...")

Sets up the worker for the result loading process.

def color_protein_pair_by_rmsd(self) -> None:
2799    def color_protein_pair_by_rmsd(self) -> None:
2800        """Colors the residues in 5 colors depending on their distance to the reference."""
2801        self._view.wait_spinner.start()
2802        self._active_task = tasks.Task(
2803            target=main_presenter_async.color_protein_pair_by_rmsd_value,
2804            args=(
2805                self._current_project,
2806                self.results_name,
2807            ),
2808            post_func=self.__await_color_protein_pair_by_rmsd,
2809        )
2810        self._active_task.start()
2811        self._view.status_bar.showMessage("Coloring protein pair by RMSD value ...")
2812        # hide unnecessary representations
2813        # fixme: it might be a problem to hide any representation at this point
2814        # cmd.hide("cartoon", tmp_protein_pair.protein_1.get_molecule_object())
2815        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")
2816        # cmd.hide("cartoon", f"{tmp_protein_pair.protein_2.get_molecule_object()}")

Colors the residues in 5 colors depending on their distance to the reference.

def display_structure_alignment(self) -> None:
2824    def display_structure_alignment(self) -> None:
2825        """Opens a window which displays the image of the structure alignment."""
2826        png_dialog = QtWidgets.QDialog(self._view)
2827        label = QtWidgets.QLabel(self._view)
2828        pathlib.Path(
2829            f"{self._workspace_path}/{self._view.ui.lbl_current_project_name.text()}/results/{self.results_name}",
2830        )
2831        self._view.ui.cb_results_analysis_options.currentText()
2832        pixmap = QtGui.QPixmap(
2833            f"{constants.CACHE_STRUCTURE_ALN_IMAGES_DIR}/structure_aln_{self._view.ui.cb_results_analysis_options.currentText()}",
2834        )
2835        # TO-DO: Create setting for min. image size
2836        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2837        label.setPixmap(pixmap)
2838        label.setScaledContents(True)
2839        png_dialog_layout = QtWidgets.QHBoxLayout()
2840        png_dialog_layout.addWidget(label)
2841        png_dialog.setLayout(png_dialog_layout)
2842        png_dialog.setWindowTitle("Image of: structure alignment")
2843        png_dialog.show()

Opens a window which displays the image of the structure alignment.

def display_distance_plot(self) -> None:
2845    def display_distance_plot(self) -> None:
2846        """Opens a window which displays the distance plot."""
2847        protein_pair_of_analysis = self._current_project.search_protein_pair(
2848            self._view.ui.cb_results_analysis_options.currentText(),
2849        )
2850
2851        tmp_dialog = plot_view.PlotView(protein_pair_of_analysis, self._current_project, self._view.ui.cb_results_analysis_options.currentText())
2852        tmp_dialog.exec_()
2853
2854        # self.distance_plot_dialog = dialog_distance_plot.DialogDistancePlot(protein_pair_of_analysis, self._current_project,
2855        #                                                                     self._view.ui.cb_results_analysis_options.currentText())
2856        # self.distance_plot_dialog.setWindowModality(Qt.WindowModal)
2857        # self.is_distance_plot_open = True
2858        # self.distance_plot_dialog.exec_()

Opens a window which displays the distance plot.

def display_distance_histogram(self) -> None:
2860    def display_distance_histogram(self) -> None:
2861        """Opens a window which displays the distance histogram."""
2862        if self.is_distance_plot_open:
2863            self.distance_plot_dialog.close()
2864            self.is_distance_plot_open = False
2865        protein_pair_of_analysis = self._current_project.search_protein_pair(
2866            self._view.ui.cb_results_analysis_options.currentText(),
2867        )
2868        dialog = dialog_distance_histogram.DialogDistanceHistogram(protein_pair_of_analysis)
2869        dialog.exec_()

Opens a window which displays the distance histogram.

def display_interesting_region(self) -> None:
2871    def display_interesting_region(self) -> None:
2872        """Displays an image of an interesting region."""
2873        if self.is_distance_plot_open:
2874            self.distance_plot_dialog.close()
2875            self.is_distance_plot_open = False
2876        png_dialog = QtWidgets.QDialog(self._view)
2877        label = QtWidgets.QLabel(self._view)
2878        file_name = self._view.ui.list_results_interest_regions.currentItem().text()
2879        pixmap = QtGui.QPixmap(f"{constants.CACHE_STRUCTURE_ALN_IMAGES_INTERESTING_REGIONS_DIR}/{file_name}")
2880        # TODO: Create setting for min. image size
2881        pixmap = pixmap.scaled(450, 450, transformMode=QtCore.Qt.SmoothTransformation)
2882        label.setPixmap(pixmap)
2883        label.setScaledContents(True)
2884        png_dialog_layout = QtWidgets.QHBoxLayout()
2885        png_dialog_layout.addWidget(label)
2886        png_dialog.setLayout(png_dialog_layout)
2887        png_dialog.setWindowTitle(f"Image of: {file_name}")
2888        png_dialog.show()

Displays an image of an interesting region.

def display_distance_table(self) -> None:
2890    def display_distance_table(self) -> None:
2891        """Displays the distances in a table."""
2892        if self.is_distance_plot_open:
2893            self.distance_plot_dialog.close()
2894            self.is_distance_plot_open = False
2895        csv_model = QtGui.QStandardItemModel()
2896        csv_model.setColumnCount(7)
2897        labels = [
2898            "Residue pair no.",
2899            "Protein 1 Chain",
2900            "Protein 1 Position",
2901            "Protein 1 Residue",
2902            "Protein 2 Chain",
2903            "Protein 2 Position",
2904            "Protein 2 Residue",
2905            "Distance in Ã…",
2906        ]
2907        csv_model.setHorizontalHeaderLabels(labels)
2908        table_dialog = QtWidgets.QDialog(self._view)
2909        table_view = QtWidgets.QTableView()
2910        table_view.setModel(csv_model)
2911
2912        tmp_protein_pair = self._current_project.search_protein_pair(
2913            self._view.ui.cb_results_analysis_options.currentText(),
2914        )
2915        csv_filepath = pathlib.Path(f"{constants.CACHE_CSV_DIR}/{tmp_protein_pair.name}.csv")
2916        if not os.path.exists(constants.CACHE_CSV_DIR):
2917            os.mkdir(constants.CACHE_CSV_DIR)
2918        tmp_protein_pair = self._current_project.search_protein_pair(self.results_name)
2919
2920        distance_data = tmp_protein_pair.distance_analysis.analysis_results.distance_data
2921        distance_data_array = np.array(
2922            [
2923                distance_data[pyssa_keys.ARRAY_DISTANCE_INDEX],
2924                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_CHAIN],
2925                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_POSITION],
2926                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_1_RESI],
2927                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_CHAIN],
2928                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_POSITION],
2929                distance_data[pyssa_keys.ARRAY_DISTANCE_PROT_2_RESI],
2930                distance_data[pyssa_keys.ARRAY_DISTANCE_DISTANCES],
2931            ],
2932        )
2933        distance_data_array_transpose = distance_data_array.transpose()
2934        with open(csv_filepath, mode="w", newline="") as file:
2935            writer = csv.writer(file, delimiter=",")
2936            writer.writerows(distance_data_array_transpose)
2937
2938        file.close()
2939
2940        with open(csv_filepath, "r", encoding="utf-8") as csv_file:
2941            i = 0
2942            for line in csv_file:
2943                tmp_list = line.split(",")
2944                # tmp_list.pop(0)
2945                standard_item_list = []
2946                pair_no_item = QtGui.QStandardItem()
2947                pair_no_item.setData(int(tmp_list[0]), role=QtCore.Qt.DisplayRole)
2948                ref_chain_item = QtGui.QStandardItem()
2949                ref_chain_item.setData(str(tmp_list[1]), role=QtCore.Qt.DisplayRole)
2950                ref_pos_item = QtGui.QStandardItem()
2951                ref_pos_item.setData(int(tmp_list[2]), role=QtCore.Qt.DisplayRole)
2952                ref_resi_item = QtGui.QStandardItem()
2953                ref_resi_item.setData(str(tmp_list[3]), role=QtCore.Qt.DisplayRole)
2954                model_chain_item = QtGui.QStandardItem()
2955                model_chain_item.setData(str(tmp_list[4]), role=QtCore.Qt.DisplayRole)
2956                model_pos_item = QtGui.QStandardItem()
2957                model_pos_item.setData(int(tmp_list[5]), role=QtCore.Qt.DisplayRole)
2958                model_resi_item = QtGui.QStandardItem()
2959                model_resi_item.setData(str(tmp_list[6]), role=QtCore.Qt.DisplayRole)
2960                distance_item = QtGui.QStandardItem()
2961                distance_item.setData(float(tmp_list[7]), role=QtCore.Qt.DisplayRole)
2962                standard_item_list.append(pair_no_item)
2963                standard_item_list.append(ref_chain_item)
2964                standard_item_list.append(ref_pos_item)
2965                standard_item_list.append(ref_resi_item)
2966                standard_item_list.append(model_chain_item)
2967                standard_item_list.append(model_pos_item)
2968                standard_item_list.append(model_resi_item)
2969                standard_item_list.append(distance_item)
2970                csv_model.insertRow(i, standard_item_list)
2971            i += 1
2972        csv_file.close()
2973        csv_model.removeRow(0)
2974        table_view.setAlternatingRowColors(True)
2975        table_view.resizeColumnsToContents()
2976        table_view.verticalHeader().setVisible(False)
2977        table_view.setSortingEnabled(True)
2978        table_view.sortByColumn(0, QtCore.Qt.AscendingOrder)
2979        table_dialog_layout = QtWidgets.QHBoxLayout()
2980        table_dialog_layout.addWidget(table_view)
2981        table_dialog.setLayout(table_dialog_layout)
2982        # styles
2983        stylesheet = """
2984        QDialog {background-color: #F6F4F8;}
2985        QTableView {background-color: white;}
2986        """
2987        table_dialog.setStyleSheet(stylesheet)
2988        table_dialog.setWindowFlag(QtCore.Qt.WindowMaximizeButtonHint, True)
2989        table_dialog.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, True)
2990        table_dialog.setModal(True)
2991        table_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)  # disables editing of cells
2992        table_dialog.setWindowTitle("Distances of Structure Alignment")
2993        table_dialog.show()

Displays the distances in a table.

def choose_manage_open_protein(self) -> None:
2998    def choose_manage_open_protein(self) -> None:
2999        """Shows the different configuration gui elements."""
3000        if self._view.ui.box_manage_choose_protein.currentText() != "":
3001            gui_elements_to_show = [
3002                self._view.ui.lbl_manage_choose_color,
3003                self._view.ui.box_manage_choose_color,
3004                self._view.ui.lbl_manage_choose_representation,
3005                self._view.ui.box_manage_choose_representation,
3006                self._view.ui.lbl_manage_choose_bg_color,
3007                self._view.ui.box_manage_choose_bg_color,
3008            ]
3009            gui_utils.show_gui_elements(gui_elements_to_show)
3010            tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3011            if (
3012                cmd.select(
3013                    name="disulfides",
3014                    selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3015                )
3016                > 0
3017            ):
3018                gui_elements_to_show = [
3019                    self._view.ui.lbl_disulfid_bond_1,
3020                    self._view.ui.lbl_disulfid_bond_2,
3021                    self._view.ui.btn_disulfid_bond_show,
3022                    self._view.ui.btn_disulfid_bond_hide,
3023                ]
3024                gui_utils.show_gui_elements(gui_elements_to_show)
3025        else:
3026            gui_elements_to_hide = [
3027                self._view.ui.lbl_manage_choose_color,
3028                self._view.ui.box_manage_choose_color,
3029                self._view.ui.lbl_manage_choose_representation,
3030                self._view.ui.box_manage_choose_representation,
3031                self._view.ui.lbl_manage_choose_bg_color,
3032                self._view.ui.box_manage_choose_bg_color,
3033                self._view.ui.lbl_disulfid_bond_1,
3034                self._view.ui.lbl_disulfid_bond_2,
3035                self._view.ui.btn_disulfid_bond_show,
3036                self._view.ui.btn_disulfid_bond_hide,
3037            ]
3038            gui_utils.hide_gui_elements(gui_elements_to_hide)

Shows the different configuration gui elements.

def choose_manage_color_selected_protein(self) -> None:
3040    def choose_manage_color_selected_protein(self) -> None:
3041        """Sets the protein color."""
3042        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3043        tmp_protein = self._current_project.search_protein(tmp_input)
3044        tmp_protein.color_protein_in_pymol(
3045            self._view.ui.box_manage_choose_color.currentText(),
3046            f"/{tmp_protein.get_molecule_object()}",
3047        )

Sets the protein color.

def choose_manage_representation(self) -> None:
3049    def choose_manage_representation(self) -> None:
3050        """Sets the representation."""
3051        tmp_input = self._view.ui.box_manage_choose_protein.currentText()
3052        tmp_protein = self._current_project.search_protein(tmp_input)
3053        tmp_selection = f"/{tmp_protein.get_molecule_object()}"
3054        if self._view.ui.box_manage_choose_representation.currentIndex() == 0:
3055            print("Please select a representation.")
3056            self._view.status_bar.showMessage("Please select a representation.")
3057        elif self._view.ui.box_manage_choose_representation.currentIndex() == 1:
3058            cmd.show("cartoon", tmp_selection)
3059            cmd.hide("ribbon", tmp_selection)
3060        elif self._view.ui.box_manage_choose_representation.currentIndex() == 2:
3061            cmd.show("ribbon", tmp_selection)
3062            cmd.hide("cartoon", tmp_selection)
3063        else:
3064            print("Missing implementation!")

Sets the representation.

def choose_manage_bg_color(self) -> None:
3066    def choose_manage_bg_color(self) -> None:
3067        """Sets the background color."""
3068        if self._view.ui.box_manage_choose_bg_color.currentIndex() == 0:
3069            print("Please select a background color.")
3070            self._view.status_bar.showMessage("Please select a background color.")
3071        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 1:
3072            cmd.bg_color("black")
3073        elif self._view.ui.box_manage_choose_bg_color.currentIndex() == 2:
3074            cmd.bg_color("white")
3075        else:
3076            print("Missing implementation!")

Sets the background color.

def show_disulfid_bonds_as_sticks(self) -> None:
3078    def show_disulfid_bonds_as_sticks(self) -> None:
3079        """Shows all disulfid bonds within the pymol session."""
3080        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3081        cmd.select(
3082            name="disulfides",
3083            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3084        )
3085        cmd.color(color="atomic", selection="disulfides and not elem C")
3086        cmd.set("valence", 0)  # this needs to be better implemented
3087        cmd.show("sticks", "disulfides")
3088        cmd.hide("sticks", "elem H")

Shows all disulfid bonds within the pymol session.

def hide_disulfid_bonds_as_sticks(self) -> None:
3090    def hide_disulfid_bonds_as_sticks(self) -> None:
3091        """Hides all disulfid bonds within the pymol session."""
3092        tmp_pymol_selection_option: str = "byres (resn CYS and name SG) within 2 of (resn CYS and name SG)"
3093        cmd.select(
3094            name="disulfides",
3095            selection=f"{self._view.ui.box_manage_choose_protein.currentText()} & {tmp_pymol_selection_option}",
3096        )
3097        cmd.hide("sticks", "disulfides")

Hides all disulfid bonds within the pymol session.

def show_representation(self) -> None:
3102    def show_representation(self) -> None:
3103        """Sets the representation."""
3104        if self._view.ui.box_representation.currentIndex() == 0:
3105            self.main_window_state.image_page.representation = ""
3106            self._view.status_bar.showMessage("Please select a representation.")
3107        elif self._view.ui.box_representation.currentIndex() == 1:
3108            cmd.show("cartoon", "all")
3109            cmd.hide("ribbon", "all")
3110            self.main_window_state.image_page.representation = "cartoon"
3111        elif self._view.ui.box_representation.currentIndex() == 2:
3112            cmd.show("ribbon", "all")
3113            cmd.hide("cartoon", "all")
3114            self.main_window_state.image_page.representation = "ribbon"
3115        else:
3116            print("Missing implementation!")

Sets the representation.

def choose_bg_color(self) -> None:
3118    def choose_bg_color(self) -> None:
3119        """Sets the background color."""
3120        if self._view.ui.box_bg_color.currentIndex() == 0:
3121            self.main_window_state.image_page.background_color = ""
3122            self._view.status_bar.showMessage("Please select a background color.")
3123        elif self._view.ui.box_bg_color.currentIndex() == 1:
3124            cmd.bg_color("black")
3125            self.main_window_state.image_page.background_color = "black"
3126        elif self._view.ui.box_bg_color.currentIndex() == 2:
3127            cmd.bg_color("white")
3128            self.main_window_state.image_page.background_color = "white"
3129        else:
3130            print("Missing implementation!")

Sets the background color.

def choose_renderer(self) -> None:
3132    def choose_renderer(self) -> None:
3133        """Sets the renderer."""
3134        if self._view.ui.box_renderer.currentIndex() == 0:
3135            self._view.status_bar.showMessage("Please select a renderer.")
3136            self._view.ui.cb_ray_tracing.hide()
3137            self._view.ui.label_26.hide()
3138        elif self._view.ui.box_renderer.currentIndex() == 1:
3139            self.renderer = "-1"
3140            self._view.ui.cb_ray_tracing.show()
3141            self._view.ui.label_26.show()
3142        elif self._view.ui.box_renderer.currentIndex() == 2:
3143            self.renderer = "0"
3144            self._view.ui.cb_ray_tracing.show()
3145            self._view.ui.label_26.show()
3146        else:
3147            print("Missing implementation!")
3148        self.main_window_state.image_page.renderer = self._view.ui.box_renderer.currentIndex()

Sets the renderer.

def choose_ray_trace_mode(self) -> None:
3150    def choose_ray_trace_mode(self) -> None:
3151        """Sets the ray-trace mode."""
3152        if self._view.ui.box_ray_trace_mode.currentIndex() == 0:
3153            self._view.status_bar.showMessage("Please select a Ray-Trace-Mode.")
3154        elif self._view.ui.box_ray_trace_mode.currentIndex() == 1:
3155            cmd.set("ray_trace_mode", 0)
3156        elif self._view.ui.box_ray_trace_mode.currentIndex() == 2:
3157            cmd.set("ray_trace_mode", 1)
3158        elif self._view.ui.box_ray_trace_mode.currentIndex() == 3:
3159            cmd.set("ray_trace_mode", 2)
3160        elif self._view.ui.box_ray_trace_mode.currentIndex() == 4:
3161            cmd.set("ray_trace_mode", 3)
3162        else:
3163            print("Missing implementation!")
3164        self.main_window_state.image_page.ray_trace_mode = self._view.ui.box_ray_trace_mode.currentIndex()

Sets the ray-trace mode.

def choose_ray_texture(self) -> None:
3166    def choose_ray_texture(self) -> None:
3167        """Sets the ray texture."""
3168        if self._view.ui.box_ray_texture.currentIndex() == 0:
3169            print("Please select a Ray Texture.")
3170            self._view.status_bar.showMessage("Please select a Ray Texture.")
3171        elif self._view.ui.box_ray_texture.currentIndex() == 1:
3172            cmd.set("ray_texture", 0)
3173        elif self._view.ui.box_ray_texture.currentIndex() == 2:
3174            cmd.set("ray_texture", 1)
3175        elif self._view.ui.box_ray_texture.currentIndex() == 3:
3176            cmd.set("ray_texture", 2)
3177        elif self._view.ui.box_ray_texture.currentIndex() == 4:
3178            cmd.set("ray_texture", 3)
3179        elif self._view.ui.box_ray_texture.currentIndex() == 5:
3180            cmd.set("ray_texture", 4)
3181        elif self._view.ui.box_ray_texture.currentIndex() == 6:
3182            cmd.set("ray_texture", 5)
3183        else:
3184            print("Missing implementation!")
3185        self.main_window_state.image_page.ray_texture = self._view.ui.box_ray_texture.currentIndex()

Sets the ray texture.

def decide_ray_tracing(self) -> None:
3187    def decide_ray_tracing(self) -> None:
3188        """Sets the ray-tracing options."""
3189        print(self._view.ui.cb_ray_tracing.isChecked())
3190        if self._view.ui.cb_ray_tracing.isChecked():
3191            self._view.ui.cb_transparent_bg.hide()
3192            self._view.ui.label_23.hide()
3193            self._view.ui.box_renderer.setEnabled(False)
3194            self._view.ui.label_10.show()
3195            self._view.ui.box_ray_trace_mode.show()
3196            self._view.ui.label_14.show()
3197            self._view.ui.box_ray_texture.show()
3198            cmd.set("ray_opaque_background", "off")
3199        else:
3200            self._view.ui.cb_transparent_bg.show()
3201            self._view.ui.label_23.show()
3202            self._view.ui.box_renderer.setEnabled(True)
3203            self._view.ui.label_10.hide()
3204            self._view.ui.box_ray_trace_mode.hide()
3205            self._view.ui.label_14.hide()
3206            self._view.ui.box_ray_texture.hide()
3207        self.main_window_state.image_page.ray_tracing = self._view.ui.cb_ray_tracing.isChecked()

Sets the ray-tracing options.

def decide_transparent_bg(self) -> None:
3209    def decide_transparent_bg(self) -> None:
3210        """Sets the transparent background."""
3211        if self._view.ui.cb_transparent_bg.isChecked():
3212            cmd.set("opaque_background", "off")
3213        else:
3214            cmd.set("opaque_background", "on")
3215        self.main_window_state.image_page.transparent_background = self._view.ui.cb_transparent_bg.isChecked()

Sets the transparent background.

@staticmethod
def update_scene() -> None:
3217    @staticmethod
3218    def update_scene() -> None:
3219        """Updates the current selected PyMOL scene."""
3220        cmd.scene(key="auto", action="update")

Updates the current selected PyMOL scene.

def save_scene(self) -> None:
3222    def save_scene(self) -> None:
3223        """Saves the current view as a new PyMOL scene."""
3224        # returns tuple with (name, bool)
3225        scene_name = QtWidgets.QInputDialog.getText(self._view, "Save Scene", "Enter scene name:")
3226        if scene_name[1]:
3227            cmd.scene(key=scene_name[0], action="append")

Saves the current view as a new PyMOL scene.

def post_preview_image(self) -> None:
3229    def post_preview_image(self) -> None:
3230        """Hides the block box of the preview process."""
3231        self.block_box_uni.hide()
3232        self.block_box_uni.destroy(True)
3233        self._view.status_bar.showMessage("Finished preview of ray-traced image.")
3234        QtWidgets.QApplication.restoreOverrideCursor()

Hides the block box of the preview process.

def preview_image(self) -> None:
3236    def preview_image(self) -> None:
3237        """Previews the image."""
3238        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3239        if self._view.ui.cb_ray_tracing.isChecked():
3240            self._view.status_bar.showMessage("Preview ray-traced image ...")
3241            # <editor-fold desc="Worker setup">
3242            # --Begin: worker setup
3243            self.tmp_thread = QtCore.QThread()
3244            self.tmp_worker = task_workers.PreviewRayImageWorker(self.renderer)
3245            self.tmp_thread = task_workers.setup_worker_for_work(
3246                self.tmp_thread,
3247                self.tmp_worker,
3248                self.display_view_page,
3249            )
3250            self.tmp_worker.finished.connect(self.post_preview_image)
3251            self.tmp_thread.start()
3252            # --End: worker setup
3253
3254            # </editor-fold>
3255            gui_utils.setup_standard_block_box(
3256                self.block_box_uni,
3257                "Preview ray-trace image",
3258                "Creating preview for the ray-traced image ...",
3259            )
3260            self.block_box_uni.exec_()
3261        else:
3262            self._view.status_bar.showMessage("Preview draw image ...")
3263            cmd.draw(2400, 2400)
3264            self._view.status_bar.showMessage("Finished preview of drawn image.")
3265            QtWidgets.QApplication.restoreOverrideCursor()

Previews the image.

def post_save_image(self) -> None:
3267    def post_save_image(self) -> None:
3268        """Displays a message box which informs that the process has finished."""
3269        self.block_box_uni.hide()
3270        self.block_box_uni.destroy(True)
3271        self._view.status_bar.showMessage("Finished image creation.")
3272        QtWidgets.QApplication.restoreOverrideCursor()
3273        basic_boxes.ok("Finished image creation", "The image has been created.", QtWidgets.QMessageBox.Information)

Displays a message box which informs that the process has finished.

def save_image(self) -> None:
3275    def save_image(self) -> None:
3276        """Saves the image as a png file."""
3277        QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
3278        if self._view.ui.cb_ray_tracing.isChecked():
3279            save_dialog = QtWidgets.QFileDialog()
3280            try:
3281                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3282                if full_file_name == ("", ""):
3283                    tools.quick_log_and_display(
3284                        "info",
3285                        "No file has been selected.",
3286                        self._view.status_bar,
3287                        "No file has been selected.",
3288                    )
3289                    return
3290                self._view.status_bar.showMessage("Creating ray-traced image ...")
3291
3292                # <editor-fold desc="Worker setup">
3293                # --Begin: worker setup
3294                self.tmp_thread = QtCore.QThread()
3295                self.tmp_worker = task_workers.SaveRayImageWorker(self.renderer, full_file_name[0])
3296                self.tmp_thread = task_workers.setup_worker_for_work(
3297                    self.tmp_thread,
3298                    self.tmp_worker,
3299                    self.display_view_page,
3300                )
3301                self.tmp_worker.finished.connect(self.post_save_image)
3302                self.tmp_thread.start()
3303                # --End: worker setup
3304
3305                # </editor-fold>
3306                gui_utils.setup_standard_block_box(
3307                    self.block_box_uni,
3308                    "Save ray-trace image",
3309                    "Creating the ray-traced image ...",
3310                )
3311                self.block_box_uni.exec_()
3312
3313                # cmd.ray(2400, 2400, renderer=int(self.renderer))
3314                # cmd.png(full_file_name[0], dpi=300)
3315
3316            except FileExistsError:
3317                tools.quick_log_and_display(
3318                    "error",
3319                    "File exists already.",
3320                    self._view.status_bar,
3321                    "File exists already.",
3322                )
3323            except pymol.CmdException:
3324                tools.quick_log_and_display(
3325                    "error",
3326                    "Unexpected Error from PyMOL while saving the " "an image",
3327                    self._view.status_bar,
3328                    "Unexpected Error from PyMOL",
3329                )
3330        else:
3331            save_dialog = QtWidgets.QFileDialog()
3332            try:
3333                full_file_name = save_dialog.getSaveFileName(caption="Save Image", filter="Image (*.png)")
3334                if full_file_name == ("", ""):
3335                    tools.quick_log_and_display(
3336                        "info",
3337                        "No file has been selected.",
3338                        self._view.status_bar,
3339                        "No file has been selected.",
3340                    )
3341                    return
3342                self._view.status_bar.showMessage("Creating draw image ...")
3343                cmd.draw(2400, 2400)
3344                cmd.png(full_file_name[0], dpi=300)
3345                self._view.status_bar.showMessage("Finished image creation.")
3346                basic_boxes.ok(
3347                    "Finished image creation",
3348                    "The image has been created.",
3349                    QtWidgets.QMessageBox.Information,
3350                )
3351            except FileExistsError:
3352                tools.quick_log_and_display(
3353                    "error",
3354                    "File exists already.",
3355                    self._view.status_bar,
3356                    "File exists already.",
3357                )
3358            except pymol.CmdException:
3359                tools.quick_log_and_display(
3360                    "error",
3361                    "Unexpected Error from PyMOL while saving the " "an image",
3362                    self._view.status_bar,
3363                    "Unexpected Error from PyMOL",
3364                )
3365            finally:
3366                QtWidgets.QApplication.restoreOverrideCursor()

Saves the image as a png file.

def open_protein_for_hotspots(self) -> None:
3371    def open_protein_for_hotspots(self) -> None:
3372        """Loads the selected protein's pymol session."""
3373        self._view.wait_spinner.start()
3374        try:
3375            tmp_name = self._view.ui.list_hotspots_choose_protein.currentItem().text()
3376        except AttributeError:
3377            self._view.wait_spinner.stop()
3378            return
3379        if self._view.ui.list_hotspots_choose_protein.currentItem().text() != "":
3380            tools.ask_to_save_pymol_session(self._current_project, self.current_session, self._application_settings)
3381            self._active_task = tasks.Task(
3382                target=main_presenter_async.open_protein_for_hotspots,
3383                args=(
3384                    tmp_name,
3385                    self._current_project,
3386                    self.current_session,
3387                ),
3388                post_func=self.__await_open_protein_for_hotspots,
3389            )
3390            self._active_task.start()
3391            self.update_status("Loading PyMOL session ...")
3392        else:
3393            self._view.wait_spinner.stop()
3394            self.update_status(self._workspace_status)

Loads the selected protein's pymol session.

@staticmethod
def hide_resi_sticks() -> None:
3425    @staticmethod
3426    def hide_resi_sticks() -> None:
3427        """Hides the balls and sticks representation of the pymol selection."""
3428        session_util.check_if_sele_is_empty()
3429        cmd.hide(representation="sticks", selection="sele")

Hides the balls and sticks representation of the pymol selection.

@staticmethod
def show_resi_sticks() -> None:
3431    @staticmethod
3432    def show_resi_sticks() -> None:
3433        """Shows the pymol selection as sticks."""
3434        session_util.check_if_sele_is_empty()
3435        cmd.show(representation="sticks", selection="sele and not hydrogens")
3436        cmd.select(name="sele", selection="sele and not hydrogens")
3437        cmd.color(color="atomic", selection="sele and not elem C")
3438        cmd.set("valence", 0)  # this needs to be better implemented

Shows the pymol selection as sticks.

@staticmethod
def zoom_resi_position() -> None:
3440    @staticmethod
3441    def zoom_resi_position() -> None:
3442        """Zooms to the pymol selection."""
3443        session_util.check_if_sele_is_empty()
3444        cmd.zoom(selection="sele", buffer=8.0, state=0, complete=0)

Zooms to the pymol selection.

def display_home_page(self) -> None:
3746    def display_home_page(self) -> None:
3747        """Displays the homepage of the plugin."""
3748        if self.is_distance_plot_open:
3749            self.distance_plot_dialog.close()
3750            self.is_distance_plot_open = False
3751        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 0, "Home")

Displays the homepage of the plugin.

def display_job_analysis_page(self) -> None:
3753    def display_job_analysis_page(self) -> None:
3754        """Displays the job analysis work area."""
3755        self._view.ui.list_analysis_batch_ref_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3756        self._view.ui.list_analysis_batch_model_chains.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
3757        # regular work area opening
3758        self._init_batch_analysis_page()
3759        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 4, "Structure Analysis")
3760        self.last_sidebar_button = styles.color_sidebar_buttons(
3761            self.last_sidebar_button,
3762            self._view.ui.btn_batch_analysis_page,
3763        )

Displays the job analysis work area.

def display_results_page(self) -> None:
3765    def display_results_page(self) -> None:
3766        """Displays the results work area."""
3767        if self.is_distance_plot_open:
3768            self.distance_plot_dialog.close()
3769            self.is_distance_plot_open = False
3770        results = []
3771        results.insert(0, "")
3772
3773        for tmp_protein_pair in self._current_project.protein_pairs:
3774            results.append(tmp_protein_pair.name)
3775            if tmp_protein_pair.name == self.results_name:
3776                pass
3777        self._view.ui.cb_results_analysis_options.clear()
3778        gui_utils.fill_combo_box(self._view.ui.cb_results_analysis_options, results)
3779
3780        desired_string: str = self.main_window_state.results_page.results_name
3781        # Find the index of the string in the combo box
3782        index = self._view.ui.cb_results_analysis_options.findText(desired_string)
3783        # Set the current index of the combo box
3784        if index != -1:
3785            self._view.ui.cb_results_analysis_options.setCurrentIndex(index)
3786        else:
3787            print(f"String '{desired_string}' not found in the combo box.")
3788
3789        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 5, "Results")
3790        self.last_sidebar_button = styles.color_sidebar_buttons(
3791            self.last_sidebar_button,
3792            self._view.ui.btn_results_page,
3793        )

Displays the results work area.

def display_image_page(self) -> None:
3795    def display_image_page(self) -> None:
3796        """Displays the image work area."""
3797        if self.is_distance_plot_open:
3798            self.distance_plot_dialog.close()
3799            self.is_distance_plot_open = False
3800        self._init_image_page()
3801
3802        if self.main_window_state.image_page.transparent_background:
3803            self._view.ui.cb_transparent_bg.setChecked(True)
3804        else:
3805            self._view.ui.cb_transparent_bg.setChecked(False)
3806        if self.main_window_state.image_page.ray_tracing:
3807            self._view.ui.cb_ray_tracing.setChecked(True)
3808        else:
3809            self._view.ui.cb_ray_tracing.setChecked(False)
3810        try:
3811            self._view.ui.box_representation.setCurrentIndex(
3812                self._view.ui.box_representation.findText(self.main_window_state.image_page.representation),
3813            )
3814            self._view.ui.box_bg_color.setCurrentIndex(
3815                self._view.ui.box_bg_color.findText(self.main_window_state.image_page.background_color),
3816            )
3817            self._view.ui.box_renderer.setCurrentIndex(self.main_window_state.image_page.renderer)
3818            self._view.ui.box_ray_trace_mode.setCurrentIndex(self.main_window_state.image_page.ray_trace_mode)
3819            self._view.ui.box_ray_texture.setCurrentIndex(self.main_window_state.image_page.ray_texture)
3820        except IndexError:
3821            constants.PYSSA_LOGGER.error("An option is invalid.")
3822
3823        if self._view.ui.box_renderer.currentText() == "":
3824            self._view.ui.cb_ray_tracing.hide()
3825            self._view.ui.label_26.hide()
3826        else:
3827            self._view.ui.cb_ray_tracing.show()
3828            self._view.ui.label_26.show()
3829
3830        if self._view.ui.cb_ray_tracing.isChecked():
3831            self._view.ui.label_10.show()
3832            self._view.ui.box_ray_trace_mode.show()
3833            self._view.ui.label_14.show()
3834            self._view.ui.box_ray_texture.show()
3835        else:
3836            self._view.ui.label_10.hide()
3837            self._view.ui.box_ray_trace_mode.hide()
3838            self._view.ui.label_14.hide()
3839            self._view.ui.box_ray_texture.hide()
3840
3841        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_image_page)
3842        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 6, "Image")

Displays the image work area.

def display_new_page(self) -> None:
3844    def display_new_page(self) -> None:
3845        """Displays the new project work area."""
3846        self._init_new_page()
3847        self._view.ui.list_new_projects.clear()
3848        # pre-process
3849        gui_elements_to_hide = [
3850            self._view.ui.lbl_new_choose_reference,
3851            self._view.ui.txt_new_choose_reference,
3852            self._view.ui.btn_new_choose_reference,
3853        ]
3854        gui_utils.hide_gui_elements(gui_elements_to_hide)
3855        self._view.status_bar.showMessage(self._workspace_label.text())
3856        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_new_projects)
3857        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 7, "Create new project")
3858        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_new_page)

Displays the new project work area.

def display_open_page(self) -> None:
3860    def display_open_page(self) -> None:
3861        """Displays the open project work area."""
3862        self._view.ui.txt_open_search.clear()
3863        self._view.ui.txt_open_selected_project.clear()
3864        if safeguard.Safeguard.check_filepath(self._workspace_path):
3865            self._view.ui.list_open_projects.clear()
3866            # pre-process
3867            self._view.status_bar.showMessage(self._workspace_label.text())
3868            try:
3869                tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_open_projects)
3870            except PermissionError:
3871                gui_utils.error_dialog_settings(
3872                    "The settings file is corrupted. Please restore the settings!",
3873                    "",
3874                    self._application_settings,
3875                )
3876                self.display_home_page()
3877                return
3878            tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 8, "Open existing project")
3879            self.last_sidebar_button = styles.color_sidebar_buttons(
3880                self.last_sidebar_button,
3881                self._view.ui.btn_open_page,
3882            )
3883        else:
3884            gui_utils.error_dialog_settings(
3885                "The settings file is corrupted. Please restore the settings!",
3886                "",
3887                self._application_settings,
3888            )
3889            self.display_home_page()

Displays the open project work area.

def display_delete_page(self) -> None:
3891    def display_delete_page(self) -> None:
3892        """Displays the "delete" project work area."""
3893        self._view.ui.txt_delete_search.clear()
3894        self._view.ui.txt_delete_selected_projects.clear()
3895        self._view.ui.list_delete_projects.clear()
3896        # pre-process
3897        self._view.status_bar.showMessage(self._workspace_label.text())
3898        tools.scan_workspace_for_valid_projects(self._workspace_path, self._view.ui.list_delete_projects)
3899        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 9, "Delete existing project")
3900        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_delete_page)

Displays the "delete" project work area.

def display_edit_page(self) -> None:
3902    def display_edit_page(self) -> None:
3903        """Displays the edit project page."""
3904        if self.is_distance_plot_open:
3905            self.distance_plot_dialog.close()
3906            self.is_distance_plot_open = False
3907        # pre-process
3908        self._view.status_bar.showMessage(self._workspace_label.text())
3909        self._init_edit_page()
3910        tools.switch_page(
3911            self._view.ui.stackedWidget,
3912            self._view.ui.lbl_page_title,
3913            13,
3914            "Edit proteins of current project",
3915        )
3916        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_edit_page)
3917        if len(self._view.ui.list_edit_project_proteins) >= 2:
3918            self._view.ui.btn_edit_existing_protein_struct.hide()
3919            self._view.ui.lbl_edit_existing_protein_struct.hide()
3920        else:
3921            self._view.ui.btn_edit_existing_protein_struct.show()
3922            self._view.ui.lbl_edit_existing_protein_struct.show()

Displays the edit project page.

def display_hotspots_page(self) -> None:
3924    def display_hotspots_page(self) -> None:
3925        """Displays the hotspots page."""
3926        if self.is_distance_plot_open:
3927            self.distance_plot_dialog.close()
3928            self.is_distance_plot_open = False
3929        try:
3930            print(self._view.ui.list_hotspots_choose_protein.currentItem().text())
3931        except AttributeError:
3932            self._view.ui.list_hotspots_choose_protein.clear()
3933            gui_elements_to_hide = [
3934                self._view.ui.lbl_hotspots_resi_no,
3935                self._view.ui.sp_hotspots_resi_no,
3936                self._view.ui.lbl_hotspots_resi_show,
3937                self._view.ui.btn_hotspots_resi_show,
3938                self._view.ui.lbl_hotspots_resi_hide,
3939                self._view.ui.btn_hotspots_resi_hide,
3940                self._view.ui.lbl_hotspots_resi_zoom,
3941                self._view.ui.btn_hotspots_resi_zoom,
3942            ]
3943            gui_utils.hide_gui_elements(gui_elements_to_hide)
3944            gui_utils.fill_list_view_with_protein_names(
3945                self._current_project,
3946                self._view.ui.list_hotspots_choose_protein,
3947            )
3948            gui_utils.fill_list_view_with_protein_pair_names(
3949                self._current_project,
3950                self._view.ui.list_hotspots_choose_protein,
3951            )
3952        # self.project_scanner.scan_project_for_valid_proteins(self._view.ui.list_hotspots_choose_protein)
3953        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 18, "Hotspots")
3954        self.last_sidebar_button = styles.color_sidebar_buttons(
3955            self.last_sidebar_button,
3956            self._view.ui.btn_hotspots_page,
3957        )

Displays the hotspots page.

def display_manage_pymol_session(self) -> None:
3959    def display_manage_pymol_session(self) -> None:
3960        """Displays the manage pymol session page."""
3961        if self.is_distance_plot_open:
3962            self.distance_plot_dialog.close()
3963            self.is_distance_plot_open = False
3964        self._view.ui.box_manage_choose_protein.clear()
3965        pymol_objs = cmd.get_object_list()
3966        pymol_objs.insert(0, "")
3967        for tmp_object in pymol_objs:
3968            self._view.ui.box_manage_choose_protein.addItem(tmp_object)
3969        self._view.ui.box_manage_choose_protein.setCurrentIndex(
3970            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_PROTEIN][0],
3971        )
3972        self._view.ui.box_manage_choose_color.setCurrentIndex(
3973            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_COLOR][0],
3974        )
3975        self._view.ui.box_manage_choose_representation.setCurrentIndex(
3976            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_REPRESENTATION][0],
3977        )
3978        self._view.ui.box_manage_choose_bg_color.setCurrentIndex(
3979            self.pymol_session_specs[pyssa_keys.SESSION_SPEC_BG_COLOR][0],
3980        )
3981        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 24, "Manage PyMOL session")
3982        self.last_sidebar_button = styles.color_sidebar_buttons(
3983            self.last_sidebar_button,
3984            self._view.ui.btn_manage_session,
3985        )
3986        gui_elements_to_hide = [
3987            self._view.ui.lbl_manage_choose_color,
3988            self._view.ui.box_manage_choose_color,
3989            self._view.ui.lbl_manage_choose_representation,
3990            self._view.ui.box_manage_choose_representation,
3991            self._view.ui.lbl_manage_choose_bg_color,
3992            self._view.ui.box_manage_choose_bg_color,
3993            self._view.ui.lbl_disulfid_bond_1,
3994            self._view.ui.lbl_disulfid_bond_2,
3995            self._view.ui.btn_disulfid_bond_show,
3996            self._view.ui.btn_disulfid_bond_hide,
3997        ]
3998        gui_utils.hide_gui_elements(gui_elements_to_hide)

Displays the manage pymol session page.

def show_add_reference(self) -> None:
4003    def show_add_reference(self) -> None:
4004        """Shows the reference input section."""
4005        # checkbox is checked
4006        self._view.ui.cb_new_add_reference.checkState()
4007        if self._view.ui.cb_new_add_reference.checkState() == 2:
4008            self._view.ui.txt_new_choose_reference.clear()
4009            self._view.ui.txt_new_choose_reference.setStyleSheet("background-color: white")
4010            self._view.ui.lbl_new_choose_reference.show()
4011            self._view.ui.txt_new_choose_reference.show()
4012            self._view.ui.btn_new_choose_reference.show()
4013            self._view.ui.btn_new_create_project.setEnabled(False)
4014            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4015            # check internet connectivity
4016            if not tools.check_internet_connectivity():
4017                gui_utils.no_internet_dialog()
4018                self._view.ui.txt_new_choose_reference.setEnabled(False)
4019                self._view.ui.lbl_new_status_choose_reference.setText("You cannot enter a PDB ID (no internet).")
4020                return
4021            self._view.ui.txt_new_choose_reference.setEnabled(True)
4022            self._view.ui.lbl_new_status_choose_reference.setText("")
4023        else:
4024            self._view.ui.lbl_new_choose_reference.hide()
4025            self._view.ui.txt_new_choose_reference.hide()
4026            self._view.ui.btn_new_choose_reference.hide()
4027            self._view.ui.lbl_new_status_choose_reference.setText("")
4028            self._view.ui.btn_new_create_project.setEnabled(True)

Shows the reference input section.

def load_reference_in_project(self) -> None:
4030    def load_reference_in_project(self) -> None:
4031        """Loads a reference in a new project."""
4032        try:
4033            # open file dialog
4034            file_name = QtWidgets.QFileDialog.getOpenFileName(
4035                self._view,
4036                "Open Reference",
4037                QtCore.QDir.homePath(),
4038                "PDB Files (*.pdb)",
4039            )
4040            if file_name == ("", ""):
4041                raise ValueError
4042            # display path in text box
4043            self._view.ui.txt_new_choose_reference.setText(str(file_name[0]))
4044            self._view.ui.txt_new_choose_reference.setEnabled(False)
4045            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4046            self._view.ui.btn_new_create_project.setEnabled(True)
4047        except ValueError:
4048            print("No file has been selected.")

Loads a reference in a new project.

def validate_reference_in_project(self) -> None:
4050    def validate_reference_in_project(self) -> None:
4051        """Checks if the entered reference protein is valid or not."""
4052        if len(self._view.ui.txt_new_choose_reference.text()) == 0:
4053            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4054            self._view.ui.lbl_new_status_choose_reference.setText("")
4055            self._view.ui.btn_new_create_project.setEnabled(False)
4056            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4057        elif len(self._view.ui.txt_new_choose_reference.text()) < 4:
4058            self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4059            styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4060            self._view.ui.btn_new_create_project.setEnabled(False)
4061            self._view.ui.lbl_new_status_choose_reference.setText("")
4062        # checks if a pdb id was entered
4063        elif len(self._view.ui.txt_new_choose_reference.text()) == 4:
4064            pdb_id = self._view.ui.txt_new_choose_reference.text().upper()
4065            try:
4066                # the pdb file gets saved in a scratch directory where it gets deleted immediately
4067                cmd.fetch(pdb_id, type="pdb", path=constants.SCRATCH_DIR)
4068                os.remove(f"{constants.SCRATCH_DIR}/{pdb_id}.pdb")
4069                cmd.reinitialize()
4070                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #000000")
4071                self._view.ui.btn_new_create_project.setEnabled(True)
4072            # if the id does not exist an exception gets raised
4073            except pymol.CmdException:
4074                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4075                return
4076            except FileNotFoundError:
4077                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4078                self._view.ui.lbl_new_status_choose_reference.setText("Invalid PDB ID.")
4079                self._view.ui.btn_new_create_project.setEnabled(False)
4080                return
4081        else:
4082            if self._view.ui.txt_new_choose_reference.text().find("/") == -1:
4083                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4084                self._view.ui.btn_new_create_project.setEnabled(False)
4085                styles.color_button_not_ready(self._view.ui.btn_new_create_project)
4086
4087            elif self._view.ui.txt_new_choose_reference.text().find("\\") == -1:
4088                self._view.ui.txt_new_choose_reference.setStyleSheet("color: #FC5457")
4089                self._view.ui.btn_new_create_project.setEnabled(False)
4090                styles.color_button_not_ready(self._view.ui.btn_new_create_project)

Checks if the entered reference protein is valid or not.

def validate_project_name(self) -> None:
4092    def validate_project_name(self) -> None:
4093        """Validates the input of the project name in real-time."""
4094        input_validator.InputValidator.validate_project_name(
4095            self._view.ui.list_new_projects,
4096            self._view.ui.txt_new_project_name,
4097            self._view.ui.lbl_new_status_project_name,
4098            self._view.ui.btn_new_create_project,
4099            self._view.ui.cb_new_add_reference,
4100        )

Validates the input of the project name in real-time.

def select_project_from_open_list(self) -> None:
4117    def select_project_from_open_list(self) -> None:
4118        """Sets the selected project name in the text box."""
4119        try:
4120            self._view.ui.txt_open_selected_project.setText(self._view.ui.list_open_projects.currentItem().text())
4121        except AttributeError:
4122            self._view.ui.txt_open_selected_project.setText("")

Sets the selected project name in the text box.

def activate_open_button(self) -> None:
4124    def activate_open_button(self) -> None:
4125        """Activates the open button."""
4126        if self._view.ui.txt_open_selected_project.text() == "":
4127            self._view.ui.btn_open_open_project.setEnabled(False)
4128        else:
4129            self._view.ui.btn_open_open_project.setEnabled(True)

Activates the open button.

def select_project_from_delete_list(self) -> None:
4134    def select_project_from_delete_list(self) -> None:
4135        """Selects a project from the project list on the delete page."""
4136        try:
4137            self._view.ui.txt_delete_selected_projects.setText(self._view.ui.list_delete_projects.currentItem().text())
4138        except AttributeError:
4139            self._view.ui.txt_delete_selected_projects.setText("")

Selects a project from the project list on the delete page.

def activate_delete_button(self) -> None:
4141    def activate_delete_button(self) -> None:
4142        """Activates the delete button."""
4143        if self._view.ui.txt_delete_selected_projects.text() == "":
4144            self._view.ui.btn_delete_delete_project.setEnabled(False)
4145        else:
4146            self._view.ui.btn_delete_delete_project.setEnabled(True)

Activates the delete button.

def display_view_page(self) -> None:
4163    def display_view_page(self) -> None:
4164        """Displays the edit project page."""
4165        if self.is_distance_plot_open:
4166            self.distance_plot_dialog.close()
4167            self.is_distance_plot_open = False
4168        self._view.ui.list_view_project_proteins.clear()
4169        self._view.ui.txtedit_view_sequence.clear()
4170        # pre-process
4171        self._view.status_bar.showMessage(self._workspace_label.text())
4172        # list all proteins from pdb directory
4173        gui_utils.fill_list_view_with_protein_names(self._current_project, self._view.ui.list_view_project_proteins)
4174
4175        tools.switch_page(
4176            self._view.ui.stackedWidget,
4177            self._view.ui.lbl_page_title,
4178            11,
4179            "View proteins of current project",
4180        )
4181        self.last_sidebar_button = styles.color_sidebar_buttons(self.last_sidebar_button, self._view.ui.btn_view_page)
4182        gui_elements_to_hide = [
4183            self._view.ui.btn_view_project_show,
4184            self._view.ui.btn_view_project_show_structure,
4185            self._view.ui.txtedit_view_sequence,
4186            self._view.ui.label_9,
4187            self._view.ui.label_11,
4188        ]
4189        gui_utils.hide_gui_elements(gui_elements_to_hide)

Displays the edit project page.

def view_show_options(self) -> None:
4191    def view_show_options(self) -> None:
4192        """Controls which gui elements get shown."""
4193        gui_elements_to_show = [
4194            # self._view.ui.btn_view_project_show,
4195            self._view.ui.btn_view_project_show_structure,
4196            self._view.ui.txtedit_view_sequence,
4197            # self._view.ui.label_9,
4198            self._view.ui.label_11,
4199        ]
4200        gui_utils.show_gui_elements(gui_elements_to_show)
4201        self.view_sequence()

Controls which gui elements get shown.

def view_sequence(self) -> None:
4203    def view_sequence(self) -> None:
4204        """Displays the sequence of the selected protein in a text box."""
4205        tmp_protein_basename = self._view.ui.list_view_project_proteins.currentItem().text()
4206        tmp_protein_sequences = self._current_project.search_protein(tmp_protein_basename).get_protein_sequences()
4207        self._view.ui.txtedit_view_sequence.clear()
4208        for tmp_sequence in tmp_protein_sequences:
4209            self._view.ui.txtedit_view_sequence.append("".join(tmp_sequence.sequence))
4210        # fixme: experimental sequence viewer gui
4211        # dialog = dialog_sequence_viewer.SequenceViewer(tmp_protein_sequences, tmp_protein_filename)
4212        # dialog.exec_()

Displays the sequence of the selected protein in a text box.

def validate_use_project_name(self) -> None:
4217    def validate_use_project_name(self) -> None:
4218        """Validates the input of the project name in real-time."""
4219        input_validator.InputValidator.validate_project_name(
4220            self._view.ui.list_use_existing_projects,
4221            self._view.ui.txt_use_project_name,
4222            self._view.ui.lbl_use_status_project_name,
4223            self._view.ui.btn_use_next,
4224        )

Validates the input of the project name in real-time.

def add_protein_structure_to_new_project(self) -> None:
4236    def add_protein_structure_to_new_project(self) -> None:
4237        """Adds the selected protein to the list which is used to create the new project."""
4238        prot_to_add = self._view.ui.list_use_available_protein_structures.currentItem().text()
4239        self._view.ui.list_use_selected_protein_structures.addItem(prot_to_add)
4240        self._view.ui.list_use_available_protein_structures.takeItem(
4241            self._view.ui.list_use_available_protein_structures.currentRow(),
4242        )
4243        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4244        if self._view.ui.list_use_available_protein_structures.count() > 0:
4245            try:
4246                self._view.ui.list_use_available_protein_structures.currentItem().setSelected(False)
4247            except AttributeError:
4248                constants.PYSSA_LOGGER.debug("No selection in use available proteins list on Use page.")

Adds the selected protein to the list which is used to create the new project.

def remove_protein_structure_to_new_project(self) -> None:
4250    def remove_protein_structure_to_new_project(self) -> None:
4251        """Removes the selected protein from the list which is used to create the new project."""
4252        prot_to_remove = self._view.ui.list_use_selected_protein_structures.currentItem()
4253        self._view.ui.list_use_selected_protein_structures.takeItem(
4254            self._view.ui.list_use_selected_protein_structures.currentRow(),
4255        )
4256        self._view.ui.list_use_available_protein_structures.addItem(prot_to_remove)
4257        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)
4258        if self._view.ui.list_use_selected_protein_structures.count() > 0:
4259            try:
4260                self._view.ui.list_use_selected_protein_structures.currentItem().setSelected(False)
4261            except AttributeError:
4262                constants.PYSSA_LOGGER.debug("No selection in use selected proteins list on Use page.")

Removes the selected protein from the list which is used to create the new project.

def show_protein_selection_for_use(self) -> None:
4264    def show_protein_selection_for_use(self) -> None:
4265        """Shows the two lists for the protein selection."""
4266        gui_elements_to_show = [
4267            self._view.ui.lbl_use_search,
4268            self._view.ui.lbl_use_status_search,
4269            self._view.ui.txt_use_search,
4270            self._view.ui.btn_use_add_available_protein_structures,
4271            self._view.ui.lbl_use_available_protein_structures,
4272            self._view.ui.list_use_available_protein_structures,
4273            self._view.ui.btn_use_remove_selected_protein_structures,
4274            self._view.ui.lbl_use_selected_protein_structures,
4275            self._view.ui.list_use_selected_protein_structures,
4276            self._view.ui.btn_use_back,
4277            self._view.ui.btn_use_create_new_project,
4278            self._view.ui.lbl_use_new_project,
4279        ]
4280        gui_utils.show_gui_elements(gui_elements_to_show)
4281        self._view.ui.txt_use_project_name.setEnabled(False)
4282        gui_elements_to_hide = [
4283            self._view.ui.btn_use_next,
4284            self._view.ui.list_use_existing_projects,
4285        ]
4286        gui_utils.hide_gui_elements(gui_elements_to_hide)
4287        gui_utils.disable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)
4288        self._view.ui.btn_use_add_available_protein_structures.setEnabled(False)
4289        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(False)

Shows the two lists for the protein selection.

def hide_protein_selection_for_use(self) -> None:
4291    def hide_protein_selection_for_use(self) -> None:
4292        """Hides the two lists for the protein selection."""
4293        gui_elements_to_show = [
4294            self._view.ui.btn_use_next,
4295            self._view.ui.list_use_existing_projects,
4296        ]
4297        gui_utils.show_gui_elements(gui_elements_to_show)
4298        self._view.ui.txt_use_project_name.setEnabled(True)
4299
4300        gui_elements_to_hide = [
4301            self._view.ui.lbl_use_search,
4302            self._view.ui.lbl_use_status_search,
4303            self._view.ui.txt_use_search,
4304            self._view.ui.btn_use_add_available_protein_structures,
4305            self._view.ui.lbl_use_available_protein_structures,
4306            self._view.ui.list_use_available_protein_structures,
4307            self._view.ui.btn_use_remove_selected_protein_structures,
4308            self._view.ui.lbl_use_selected_protein_structures,
4309            self._view.ui.list_use_selected_protein_structures,
4310            self._view.ui.btn_use_back,
4311            self._view.ui.btn_use_create_new_project,
4312            self._view.ui.lbl_use_new_project,
4313        ]
4314        gui_utils.hide_gui_elements(gui_elements_to_hide)
4315        gui_utils.enable_text_box(self._view.ui.txt_use_project_name, self._view.ui.lbl_use_project_name)

Hides the two lists for the protein selection.

def use_enable_add(self) -> None:
4317    def use_enable_add(self) -> None:
4318        """Enables the add button."""
4319        self._view.ui.btn_use_add_available_protein_structures.setEnabled(True)

Enables the add button.

def use_enable_remove(self) -> None:
4321    def use_enable_remove(self) -> None:
4322        """Enables the remove button."""
4323        self._view.ui.btn_use_remove_selected_protein_structures.setEnabled(True)

Enables the remove button.

def display_esm_pred_mono(self) -> None:
4341    def display_esm_pred_mono(self) -> None:
4342        """Displays the esm_fold monomer page."""
4343        self._init_esm_pred_mono_page()
4344        gui_elements_to_show = [
4345            self._view.ui.lbl_esm_prot_to_predict,
4346            self._view.ui.table_esm_prot_to_predict,
4347            self._view.ui.btn_esm_seq_to_predict,
4348        ]
4349        gui_elements_to_hide = [
4350            self._view.ui.btn_esm_seq_to_predict_remove,
4351            self._view.ui.lbl_esm_prot_name,
4352            self._view.ui.txt_esm_prot_name,
4353            self._view.ui.lbl_esm_prot_name_status,
4354            self._view.ui.btn_esm_back,
4355            self._view.ui.btn_esm_next,
4356            self._view.ui.lbl_esm_prot_seq,
4357            self._view.ui.txt_esm_prot_seq,
4358            self._view.ui.lbl_esm_prot_seq_status,
4359            self._view.ui.btn_esm_back_2,
4360            self._view.ui.btn_esm_next_2,
4361            self._view.ui.btn_esm_predict,
4362        ]
4363        gui_utils.show_gui_elements(gui_elements_to_show)
4364        gui_utils.hide_gui_elements(gui_elements_to_hide)
4365        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4366        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 1, "ESMFold Monomer Prediction")
4367        self.last_sidebar_button = styles.color_sidebar_buttons(
4368            self.last_sidebar_button,
4369            self._view.ui.btn_pred_cloud_monomer_page,
4370        )

Displays the esm_fold monomer page.

def cloud_esm_validate_protein_name(self) -> None:
4372    def cloud_esm_validate_protein_name(self) -> None:
4373        """Validates the input of the protein name in real-time."""
4374        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4375            self._view.ui.txt_esm_prot_name.text(),
4376            self._view.ui.table_esm_prot_to_predict,
4377        ):
4378            self._view.ui.lbl_esm_prot_name_status.setText("Protein name already used.")
4379            self._view.ui.btn_esm_next.setEnabled(False)
4380            styles.color_button_not_ready(self._view.ui.btn_esm_next)
4381        else:
4382            self._view.ui.btn_esm_next.setEnabled(True)
4383            tools.validate_protein_name(
4384                self._view.ui.txt_esm_prot_name,
4385                self._view.ui.lbl_esm_prot_name_status,
4386                self._view.ui.btn_esm_next,
4387            )

Validates the input of the protein name in real-time.

def cloud_esm_validate_protein_sequence(self) -> None:
4389    def cloud_esm_validate_protein_sequence(self) -> None:
4390        """Validates the input of the protein sequence in real-time."""
4391        tools.validate_protein_sequence(
4392            self._view.ui.txt_esm_prot_seq,
4393            self._view.ui.lbl_esm_prot_seq_status,
4394            self._view.ui.btn_esm_next_2,
4395        )

Validates the input of the protein sequence in real-time.

def setup_defaults_esm_monomer_prediction(self) -> None:
4397    def setup_defaults_esm_monomer_prediction(self) -> None:
4398        """Sets up the default values for the page."""
4399        # clears everything
4400        self._view.ui.txt_esm_prot_name.clear()
4401        self._view.ui.txt_esm_prot_seq.clear()
4402        # sets up defaults: Prediction
4403        self._view.ui.btn_esm_next.setEnabled(False)
4404        self._view.ui.btn_esm_next_2.setEnabled(False)
4405        self._view.ui.lbl_esm_prot_name_status.setText("")
4406        self._view.ui.lbl_esm_prot_seq_status.setText("")

Sets up the default values for the page.

def cloud_esm_add_seq_to_predict(self) -> None:
4408    def cloud_esm_add_seq_to_predict(self) -> None:
4409        """Shows the gui elements to add a sequence to the protein to predict."""
4410        gui_elements_to_show = [
4411            self._view.ui.lbl_esm_prot_to_predict,
4412            self._view.ui.table_esm_prot_to_predict,
4413            self._view.ui.lbl_esm_prot_name,
4414            self._view.ui.txt_esm_prot_name,
4415            self._view.ui.lbl_esm_prot_name_status,
4416            self._view.ui.btn_esm_back,
4417            self._view.ui.btn_esm_next,
4418        ]
4419        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4420        gui_elements_to_hide = [
4421            self._view.ui.btn_esm_seq_to_predict_remove,
4422            self._view.ui.btn_esm_seq_to_predict,
4423            self._view.ui.lbl_esm_prot_seq,
4424            self._view.ui.txt_esm_prot_seq,
4425            self._view.ui.lbl_esm_prot_seq_status,
4426            self._view.ui.btn_esm_back_2,
4427            self._view.ui.btn_esm_next_2,
4428            self._view.ui.btn_esm_predict,
4429        ]
4430        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4431        gui_utils.show_gui_elements(gui_elements_to_show)
4432        gui_utils.hide_gui_elements(gui_elements_to_hide)
4433        self._view.ui.btn_esm_next.setEnabled(False)
4434        self._view.ui.txt_esm_prot_name.clear()
4435        styles.color_button_not_ready(self._view.ui.btn_esm_next)
4436        if self._view.ui.table_esm_prot_to_predict.rowCount() > 0:
4437            try:
4438                self._view.ui.table_esm_prot_to_predict.currentItem().setSelected(False)
4439            except AttributeError:
4440                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")

Shows the gui elements to add a sequence to the protein to predict.

def cloud_esm_back(self) -> None:
4442    def cloud_esm_back(self) -> None:
4443        """Hides the gui elements for the protein name."""
4444        gui_elements_to_show = [
4445            self._view.ui.lbl_esm_prot_to_predict,
4446            self._view.ui.table_esm_prot_to_predict,
4447            self._view.ui.btn_esm_seq_to_predict_remove,
4448            self._view.ui.btn_esm_seq_to_predict,
4449        ]
4450        gui_elements_to_hide = [
4451            self._view.ui.lbl_esm_prot_name,
4452            self._view.ui.txt_esm_prot_name,
4453            self._view.ui.lbl_esm_prot_name_status,
4454            self._view.ui.btn_esm_back,
4455            self._view.ui.btn_esm_next,
4456            self._view.ui.lbl_esm_prot_seq,
4457            self._view.ui.txt_esm_prot_seq,
4458            self._view.ui.lbl_esm_prot_seq_status,
4459            self._view.ui.btn_esm_back_2,
4460            self._view.ui.btn_esm_next_2,
4461            self._view.ui.btn_esm_predict,
4462        ]
4463        gui_utils.show_gui_elements(gui_elements_to_show)
4464        gui_utils.hide_gui_elements(gui_elements_to_hide)
4465        self.cloud_esm_check_if_table_is_empty()
4466        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)

Hides the gui elements for the protein name.

def cloud_esm_next(self) -> None:
4468    def cloud_esm_next(self) -> None:
4469        """Shows the gui elements for the protein name."""
4470        gui_elements_to_show = [
4471            self._view.ui.lbl_esm_prot_to_predict,
4472            self._view.ui.table_esm_prot_to_predict,
4473            self._view.ui.lbl_esm_prot_name,
4474            self._view.ui.txt_esm_prot_name,
4475            self._view.ui.lbl_esm_prot_seq,
4476            self._view.ui.txt_esm_prot_seq,
4477            self._view.ui.lbl_esm_prot_seq_status,
4478            self._view.ui.btn_esm_back_2,
4479            self._view.ui.btn_esm_next_2,
4480        ]
4481        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4482        gui_elements_to_hide = [
4483            self._view.ui.btn_esm_seq_to_predict_remove,
4484            self._view.ui.btn_esm_seq_to_predict,
4485            self._view.ui.lbl_esm_prot_name_status,
4486            self._view.ui.btn_esm_back,
4487            self._view.ui.btn_esm_next,
4488            self._view.ui.btn_esm_predict,
4489        ]
4490        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4491        gui_utils.show_gui_elements(gui_elements_to_show)
4492        gui_utils.hide_gui_elements(gui_elements_to_hide)
4493        self._view.ui.txt_esm_prot_seq.clear()

Shows the gui elements for the protein name.

def cloud_esm_back_2(self) -> None:
4495    def cloud_esm_back_2(self) -> None:
4496        """Hides the gui elements for the protein sequence."""
4497        gui_elements_to_show = [
4498            self._view.ui.lbl_esm_prot_to_predict,
4499            self._view.ui.table_esm_prot_to_predict,
4500            self._view.ui.lbl_esm_prot_name,
4501            self._view.ui.txt_esm_prot_name,
4502            self._view.ui.lbl_esm_prot_name_status,
4503            self._view.ui.btn_esm_back,
4504            self._view.ui.btn_esm_next,
4505        ]
4506        gui_elements_to_hide = [
4507            self._view.ui.btn_esm_seq_to_predict_remove,
4508            self._view.ui.btn_esm_seq_to_predict,
4509            self._view.ui.lbl_esm_prot_seq,
4510            self._view.ui.txt_esm_prot_seq,
4511            self._view.ui.lbl_esm_prot_seq_status,
4512            self._view.ui.btn_esm_back_2,
4513            self._view.ui.btn_esm_next_2,
4514            self._view.ui.btn_esm_predict,
4515        ]
4516        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4517        gui_utils.disable_text_box(self._view.ui.txt_esm_prot_seq, self._view.ui.lbl_esm_prot_seq)
4518        gui_utils.show_gui_elements(gui_elements_to_show)
4519        gui_utils.hide_gui_elements(gui_elements_to_hide)

Hides the gui elements for the protein sequence.

def cloud_esm_add_protein(self) -> None:
4521    def cloud_esm_add_protein(self) -> None:
4522        """Adds protein to the list of proteins to predict."""
4523        self._view.ui.table_esm_prot_to_predict.setRowCount(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4524        self._view.ui.table_esm_prot_to_predict.insertRow(self._view.ui.table_esm_prot_to_predict.rowCount() + 1)
4525        self._view.ui.table_esm_prot_to_predict.setItem(
4526            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4527            0,
4528            QtWidgets.QTableWidgetItem("A"),
4529        )
4530        self._view.ui.table_esm_prot_to_predict.setItem(
4531            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4532            1,
4533            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_seq.toPlainText()),
4534        )
4535        self._view.ui.table_esm_prot_to_predict.setVerticalHeaderItem(
4536            self._view.ui.table_esm_prot_to_predict.rowCount() - 1,
4537            QtWidgets.QTableWidgetItem(self._view.ui.txt_esm_prot_name.text()),
4538        )
4539        self._view.ui.table_esm_prot_to_predict.resizeColumnsToContents()
4540        self.cloud_esm_check_if_table_is_empty()
4541        gui_elements_to_show = [
4542            self._view.ui.lbl_esm_prot_to_predict,
4543            self._view.ui.table_esm_prot_to_predict,
4544            self._view.ui.btn_esm_seq_to_predict_remove,
4545            self._view.ui.btn_esm_seq_to_predict,
4546            self._view.ui.btn_esm_predict,
4547        ]
4548        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4549        gui_elements_to_hide = [
4550            self._view.ui.lbl_esm_prot_name,
4551            self._view.ui.txt_esm_prot_name,
4552            self._view.ui.lbl_esm_prot_name_status,
4553            self._view.ui.btn_esm_back,
4554            self._view.ui.btn_esm_next,
4555            self._view.ui.lbl_esm_prot_seq,
4556            self._view.ui.txt_esm_prot_seq,
4557            self._view.ui.lbl_esm_prot_seq_status,
4558            self._view.ui.btn_esm_back_2,
4559            self._view.ui.btn_esm_next_2,
4560        ]
4561        gui_utils.show_gui_elements(gui_elements_to_show)
4562        gui_utils.hide_gui_elements(gui_elements_to_hide)
4563        self._view.ui.btn_esm_predict.setEnabled(True)
4564        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4565        self.setup_defaults_esm_monomer_prediction()

Adds protein to the list of proteins to predict.

def cloud_esm_remove(self) -> None:
4567    def cloud_esm_remove(self) -> None:
4568        """Removes a protein from the list of proteins to predict."""
4569        self._view.ui.table_esm_prot_to_predict.removeRow(self._view.ui.table_esm_prot_to_predict.currentRow())
4570        gui_elements_to_show = [
4571            self._view.ui.lbl_esm_prot_to_predict,
4572            self._view.ui.table_esm_prot_to_predict,
4573            self._view.ui.btn_esm_seq_to_predict_remove,
4574            self._view.ui.btn_esm_seq_to_predict,
4575            self._view.ui.btn_esm_predict,
4576        ]
4577        gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4578        gui_elements_to_hide = [
4579            self._view.ui.lbl_esm_prot_name,
4580            self._view.ui.txt_esm_prot_name,
4581            self._view.ui.lbl_esm_prot_name_status,
4582            self._view.ui.btn_esm_back,
4583            self._view.ui.btn_esm_next,
4584            self._view.ui.lbl_esm_prot_seq,
4585            self._view.ui.txt_esm_prot_seq,
4586            self._view.ui.lbl_esm_prot_seq_status,
4587            self._view.ui.btn_esm_back_2,
4588            self._view.ui.btn_esm_next_2,
4589        ]
4590        gui_utils.show_gui_elements(gui_elements_to_show)
4591        gui_utils.hide_gui_elements(gui_elements_to_hide)
4592        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(False)
4593        self.cloud_esm_check_if_table_is_empty()

Removes a protein from the list of proteins to predict.

def cloud_esm_item_changed(self) -> None:
4595    def cloud_esm_item_changed(self) -> None:
4596        """Enables the remove button."""
4597        self._view.ui.btn_esm_seq_to_predict_remove.setEnabled(True)

Enables the remove button.

def cloud_esm_check_if_table_is_empty(self) -> None:
4599    def cloud_esm_check_if_table_is_empty(self) -> None:
4600        """Checks if the table proteins to predict is empty."""
4601        if self._view.ui.table_esm_prot_to_predict.rowCount() == 0:
4602            styles.color_button_not_ready(self._view.ui.btn_esm_predict)
4603            self._view.ui.btn_esm_predict.setEnabled(False)
4604            gui_elements_to_show = [
4605                self._view.ui.lbl_esm_prot_to_predict,
4606                self._view.ui.table_esm_prot_to_predict,
4607                self._view.ui.btn_esm_seq_to_predict,
4608            ]
4609            gui_utils.enable_text_box(self._view.ui.txt_esm_prot_name, self._view.ui.lbl_esm_prot_name)
4610            gui_elements_to_hide = [
4611                self._view.ui.btn_esm_seq_to_predict_remove,
4612                self._view.ui.lbl_esm_prot_name,
4613                self._view.ui.txt_esm_prot_name,
4614                self._view.ui.lbl_esm_prot_name_status,
4615                self._view.ui.btn_esm_back,
4616                self._view.ui.btn_esm_next,
4617                self._view.ui.lbl_esm_prot_seq,
4618                self._view.ui.txt_esm_prot_seq,
4619                self._view.ui.lbl_esm_prot_seq_status,
4620                self._view.ui.btn_esm_back_2,
4621                self._view.ui.btn_esm_next_2,
4622                self._view.ui.btn_esm_predict,
4623            ]
4624            gui_utils.show_gui_elements(gui_elements_to_show)
4625            gui_utils.hide_gui_elements(gui_elements_to_hide)
4626        else:
4627            self._view.ui.btn_esm_predict.setEnabled(True)

Checks if the table proteins to predict is empty.

def display_local_pred_mono(self) -> None:
4645    def display_local_pred_mono(self) -> None:
4646        """Displays the local prediction monomer page."""
4647        # checks internet connection
4648        if not tools.check_internet_connectivity():
4649            gui_utils.no_internet_dialog()
4650            return
4651        self._init_local_pred_mono_page()
4652        gui_elements_to_show = [
4653            self._view.ui.lbl_pred_mono_prot_to_predict,
4654            self._view.ui.table_pred_mono_prot_to_predict,
4655            self._view.ui.btn_pred_mono_seq_to_predict,
4656        ]
4657        gui_elements_to_hide = [
4658            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4659            self._view.ui.lbl_pred_mono_prot_name,
4660            self._view.ui.txt_pred_mono_prot_name,
4661            self._view.ui.lbl_pred_mono_prot_name_status,
4662            self._view.ui.btn_pred_mono_back,
4663            self._view.ui.btn_pred_mono_next,
4664            self._view.ui.lbl_pred_mono_seq_name,
4665            self._view.ui.txt_pred_mono_seq_name,
4666            self._view.ui.lbl_pred_mono_seq_name_status,
4667            self._view.ui.btn_pred_mono_back_2,
4668            self._view.ui.btn_pred_mono_add_protein,
4669            self._view.ui.lbl_pred_mono_advanced_config,
4670            self._view.ui.btn_pred_mono_advanced_config,
4671            self._view.ui.btn_pred_mono_predict,
4672        ]
4673        gui_utils.show_gui_elements(gui_elements_to_show)
4674        gui_utils.hide_gui_elements(gui_elements_to_hide)
4675        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4676        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 19, "Local Monomer Prediction")
4677        self.last_sidebar_button = styles.color_sidebar_buttons(
4678            self.last_sidebar_button,
4679            self._view.ui.btn_pred_local_monomer_page,
4680        )

Displays the local prediction monomer page.

def local_pred_mono_validate_protein_name(self) -> None:
4682    def local_pred_mono_validate_protein_name(self) -> None:
4683        """Validates the input of the protein name in real-time."""
4684        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
4685            self._view.ui.txt_pred_mono_prot_name.text(),
4686            self._view.ui.table_pred_mono_prot_to_predict,
4687        ):
4688            self._view.ui.lbl_pred_mono_prot_name_status.setText("Protein name already used.")
4689            self._view.ui.btn_pred_mono_next.setEnabled(False)
4690            styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4691        else:
4692            self._view.ui.btn_pred_mono_next.setEnabled(True)
4693            tools.validate_protein_name(
4694                self._view.ui.txt_pred_mono_prot_name,
4695                self._view.ui.lbl_pred_mono_prot_name_status,
4696                self._view.ui.btn_pred_mono_next,
4697            )

Validates the input of the protein name in real-time.

def local_pred_mono_validate_protein_sequence(self) -> None:
4699    def local_pred_mono_validate_protein_sequence(self) -> None:
4700        """Validates the input of the protein sequence in real-time."""
4701        tools.validate_protein_sequence(
4702            self._view.ui.txt_pred_mono_seq_name,
4703            self._view.ui.lbl_pred_mono_seq_name_status,
4704            self._view.ui.btn_pred_mono_add_protein,
4705        )

Validates the input of the protein sequence in real-time.

def show_prediction_configuration(self) -> None:
4707    def show_prediction_configuration(self) -> None:
4708        """Opens the prediction configuration dialog window."""
4709        config = dialog_advanced_prediction_configurations.DialogAdvancedPredictionConfigurations(
4710            self.prediction_configuration,
4711        )
4712        config.exec_()
4713        self.prediction_configuration.amber_force_field = config.prediction_config.amber_force_field
4714        self.prediction_configuration.templates = config.prediction_config.templates

Opens the prediction configuration dialog window.

def setup_defaults_monomer_prediction(self) -> None:
4716    def setup_defaults_monomer_prediction(self) -> None:
4717        """Sets up the defaults for the page."""
4718        # clears everything
4719        self._view.ui.txt_pred_mono_prot_name.clear()
4720        self._view.ui.txt_pred_mono_seq_name.clear()
4721        # sets up defaults: Prediction
4722        self._view.ui.btn_pred_mono_next.setEnabled(False)
4723        self._view.ui.btn_pred_mono_add_protein.setEnabled(False)
4724        self._view.ui.lbl_pred_mono_prot_name_status.setText("")
4725        self._view.ui.lbl_pred_mono_seq_name_status.setText("")

Sets up the defaults for the page.

def local_pred_mono_add_seq_to_predict(self) -> None:
4727    def local_pred_mono_add_seq_to_predict(self) -> None:
4728        """Shows the gui elements for the protein name."""
4729        gui_elements_to_show = [
4730            self._view.ui.lbl_pred_mono_prot_to_predict,
4731            self._view.ui.table_pred_mono_prot_to_predict,
4732            self._view.ui.lbl_pred_mono_prot_name,
4733            self._view.ui.txt_pred_mono_prot_name,
4734            self._view.ui.lbl_pred_mono_prot_name_status,
4735            self._view.ui.btn_pred_mono_back,
4736            self._view.ui.btn_pred_mono_next,
4737        ]
4738        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4739        gui_elements_to_hide = [
4740            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4741            self._view.ui.btn_pred_mono_seq_to_predict,
4742            self._view.ui.lbl_pred_mono_seq_name,
4743            self._view.ui.txt_pred_mono_seq_name,
4744            self._view.ui.lbl_pred_mono_seq_name_status,
4745            self._view.ui.btn_pred_mono_back_2,
4746            self._view.ui.btn_pred_mono_add_protein,
4747            self._view.ui.lbl_pred_mono_advanced_config,
4748            self._view.ui.btn_pred_mono_advanced_config,
4749            self._view.ui.btn_pred_mono_predict,
4750        ]
4751        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4752        gui_utils.show_gui_elements(gui_elements_to_show)
4753        gui_utils.hide_gui_elements(gui_elements_to_hide)
4754        self._view.ui.btn_pred_mono_next.setEnabled(False)
4755        self._view.ui.txt_pred_mono_prot_name.clear()
4756        styles.color_button_not_ready(self._view.ui.btn_pred_mono_next)
4757        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() > 0:
4758            try:
4759                self._view.ui.table_pred_mono_prot_to_predict.currentItem().setSelected(False)
4760            except AttributeError:
4761                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")

Shows the gui elements for the protein name.

def local_pred_mono_back(self) -> None:
4763    def local_pred_mono_back(self) -> None:
4764        """Hides the gui elements for the protein name."""
4765        gui_elements_to_show = [
4766            self._view.ui.lbl_pred_mono_prot_to_predict,
4767            self._view.ui.table_pred_mono_prot_to_predict,
4768            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4769            self._view.ui.btn_pred_mono_seq_to_predict,
4770        ]
4771        gui_elements_to_hide = [
4772            self._view.ui.lbl_pred_mono_prot_name,
4773            self._view.ui.txt_pred_mono_prot_name,
4774            self._view.ui.lbl_pred_mono_prot_name_status,
4775            self._view.ui.btn_pred_mono_back,
4776            self._view.ui.btn_pred_mono_next,
4777            self._view.ui.lbl_pred_mono_seq_name,
4778            self._view.ui.txt_pred_mono_seq_name,
4779            self._view.ui.lbl_pred_mono_seq_name_status,
4780            self._view.ui.btn_pred_mono_back_2,
4781            self._view.ui.btn_pred_mono_add_protein,
4782            self._view.ui.lbl_pred_mono_advanced_config,
4783            self._view.ui.btn_pred_mono_advanced_config,
4784            self._view.ui.btn_pred_mono_predict,
4785        ]
4786        gui_utils.show_gui_elements(gui_elements_to_show)
4787        gui_utils.hide_gui_elements(gui_elements_to_hide)
4788        self.local_pred_mono_check_if_table_is_empty()
4789        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)

Hides the gui elements for the protein name.

def local_pred_mono_next(self) -> None:
4791    def local_pred_mono_next(self) -> None:
4792        """Shows the gui elements for the protein sequence."""
4793        gui_elements_to_show = [
4794            self._view.ui.lbl_pred_mono_prot_to_predict,
4795            self._view.ui.table_pred_mono_prot_to_predict,
4796            self._view.ui.lbl_pred_mono_prot_name,
4797            self._view.ui.txt_pred_mono_prot_name,
4798            self._view.ui.lbl_pred_mono_seq_name,
4799            self._view.ui.txt_pred_mono_seq_name,
4800            self._view.ui.lbl_pred_mono_seq_name_status,
4801            self._view.ui.btn_pred_mono_back_2,
4802            self._view.ui.btn_pred_mono_add_protein,
4803        ]
4804        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4805        gui_elements_to_hide = [
4806            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4807            self._view.ui.btn_pred_mono_seq_to_predict,
4808            self._view.ui.lbl_pred_mono_prot_name_status,
4809            self._view.ui.btn_pred_mono_back,
4810            self._view.ui.btn_pred_mono_next,
4811            self._view.ui.lbl_pred_mono_advanced_config,
4812            self._view.ui.btn_pred_mono_advanced_config,
4813            self._view.ui.btn_pred_mono_predict,
4814        ]
4815        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4816        gui_utils.show_gui_elements(gui_elements_to_show)
4817        gui_utils.hide_gui_elements(gui_elements_to_hide)
4818        self._view.ui.txt_pred_mono_seq_name.clear()

Shows the gui elements for the protein sequence.

def local_pred_mono_back_2(self) -> None:
4820    def local_pred_mono_back_2(self) -> None:
4821        """Hides the gui elements for the protein sequence."""
4822        gui_elements_to_show = [
4823            self._view.ui.lbl_pred_mono_prot_to_predict,
4824            self._view.ui.table_pred_mono_prot_to_predict,
4825            self._view.ui.lbl_pred_mono_prot_name,
4826            self._view.ui.txt_pred_mono_prot_name,
4827            self._view.ui.lbl_pred_mono_prot_name_status,
4828            self._view.ui.btn_pred_mono_back,
4829            self._view.ui.btn_pred_mono_next,
4830        ]
4831        gui_elements_to_hide = [
4832            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4833            self._view.ui.btn_pred_mono_seq_to_predict,
4834            self._view.ui.lbl_pred_mono_seq_name,
4835            self._view.ui.txt_pred_mono_seq_name,
4836            self._view.ui.lbl_pred_mono_seq_name_status,
4837            self._view.ui.btn_pred_mono_back_2,
4838            self._view.ui.btn_pred_mono_add_protein,
4839            self._view.ui.lbl_pred_mono_advanced_config,
4840            self._view.ui.btn_pred_mono_advanced_config,
4841            self._view.ui.btn_pred_mono_predict,
4842        ]
4843        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4844        gui_utils.disable_text_box(self._view.ui.txt_pred_mono_seq_name, self._view.ui.lbl_pred_mono_seq_name)
4845        gui_utils.show_gui_elements(gui_elements_to_show)
4846        gui_utils.hide_gui_elements(gui_elements_to_hide)

Hides the gui elements for the protein sequence.

def local_pred_mono_add_protein(self) -> None:
4848    def local_pred_mono_add_protein(self) -> None:
4849        """Adds protein to the list of proteins to predict."""
4850        self._view.ui.table_pred_mono_prot_to_predict.setRowCount(
4851            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4852        )
4853        self._view.ui.table_pred_mono_prot_to_predict.insertRow(
4854            self._view.ui.table_pred_mono_prot_to_predict.rowCount() + 1,
4855        )
4856        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4857            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4858            0,
4859            QtWidgets.QTableWidgetItem("A"),
4860        )
4861        self._view.ui.table_pred_mono_prot_to_predict.setItem(
4862            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4863            1,
4864            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_seq_name.toPlainText()),
4865        )
4866        self._view.ui.table_pred_mono_prot_to_predict.setVerticalHeaderItem(
4867            self._view.ui.table_pred_mono_prot_to_predict.rowCount() - 1,
4868            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_mono_prot_name.text()),
4869        )
4870        self._view.ui.table_pred_mono_prot_to_predict.resizeColumnsToContents()
4871        self.local_pred_mono_check_if_table_is_empty()
4872        gui_elements_to_show = [
4873            self._view.ui.lbl_pred_mono_prot_to_predict,
4874            self._view.ui.table_pred_mono_prot_to_predict,
4875            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4876            self._view.ui.btn_pred_mono_seq_to_predict,
4877            self._view.ui.lbl_pred_mono_advanced_config,
4878            self._view.ui.btn_pred_mono_advanced_config,
4879            self._view.ui.btn_pred_mono_predict,
4880        ]
4881        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4882        gui_elements_to_hide = [
4883            self._view.ui.lbl_pred_mono_prot_name,
4884            self._view.ui.txt_pred_mono_prot_name,
4885            self._view.ui.lbl_pred_mono_prot_name_status,
4886            self._view.ui.btn_pred_mono_back,
4887            self._view.ui.btn_pred_mono_next,
4888            self._view.ui.lbl_pred_mono_seq_name,
4889            self._view.ui.txt_pred_mono_seq_name,
4890            self._view.ui.lbl_pred_mono_seq_name_status,
4891            self._view.ui.btn_pred_mono_back_2,
4892            self._view.ui.btn_pred_mono_add_protein,
4893        ]
4894        gui_utils.show_gui_elements(gui_elements_to_show)
4895        gui_utils.hide_gui_elements(gui_elements_to_hide)
4896        self._view.ui.btn_pred_mono_predict.setEnabled(True)
4897        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4898        self.setup_defaults_monomer_prediction()

Adds protein to the list of proteins to predict.

def local_pred_mono_remove(self) -> None:
4900    def local_pred_mono_remove(self) -> None:
4901        """Removes the selected protein from the list of proteins to predict."""
4902        self._view.ui.table_pred_mono_prot_to_predict.removeRow(
4903            self._view.ui.table_pred_mono_prot_to_predict.currentRow(),
4904        )
4905        gui_elements_to_show = [
4906            self._view.ui.lbl_pred_mono_prot_to_predict,
4907            self._view.ui.table_pred_mono_prot_to_predict,
4908            self._view.ui.btn_pred_mono_seq_to_predict_remove,
4909            self._view.ui.btn_pred_mono_seq_to_predict,
4910            self._view.ui.lbl_pred_mono_advanced_config,
4911            self._view.ui.btn_pred_mono_advanced_config,
4912            self._view.ui.btn_pred_mono_predict,
4913        ]
4914        gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4915        gui_elements_to_hide = [
4916            self._view.ui.lbl_pred_mono_prot_name,
4917            self._view.ui.txt_pred_mono_prot_name,
4918            self._view.ui.lbl_pred_mono_prot_name_status,
4919            self._view.ui.btn_pred_mono_back,
4920            self._view.ui.btn_pred_mono_next,
4921            self._view.ui.lbl_pred_mono_seq_name,
4922            self._view.ui.txt_pred_mono_seq_name,
4923            self._view.ui.lbl_pred_mono_seq_name_status,
4924            self._view.ui.btn_pred_mono_back_2,
4925            self._view.ui.btn_pred_mono_add_protein,
4926        ]
4927        gui_utils.show_gui_elements(gui_elements_to_show)
4928        gui_utils.hide_gui_elements(gui_elements_to_hide)
4929        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(False)
4930        self.local_pred_mono_check_if_table_is_empty()

Removes the selected protein from the list of proteins to predict.

def local_pred_mono_item_changed(self) -> None:
4932    def local_pred_mono_item_changed(self) -> None:
4933        """Enables the remove button."""
4934        self._view.ui.btn_pred_mono_seq_to_predict_remove.setEnabled(True)

Enables the remove button.

def local_pred_mono_check_if_table_is_empty(self) -> None:
4936    def local_pred_mono_check_if_table_is_empty(self) -> None:
4937        """Checks if the table proteins to predict is empty."""
4938        if self._view.ui.table_pred_mono_prot_to_predict.rowCount() == 0:
4939            styles.color_button_not_ready(self._view.ui.btn_pred_mono_predict)
4940            self._view.ui.btn_pred_mono_predict.setEnabled(False)
4941            gui_elements_to_show = [
4942                self._view.ui.lbl_pred_mono_prot_to_predict,
4943                self._view.ui.table_pred_mono_prot_to_predict,
4944                self._view.ui.btn_pred_mono_seq_to_predict,
4945            ]
4946            gui_utils.enable_text_box(self._view.ui.txt_pred_mono_prot_name, self._view.ui.lbl_pred_mono_prot_name)
4947            gui_elements_to_hide = [
4948                self._view.ui.btn_pred_mono_seq_to_predict_remove,
4949                self._view.ui.lbl_pred_mono_prot_name,
4950                self._view.ui.txt_pred_mono_prot_name,
4951                self._view.ui.lbl_pred_mono_prot_name_status,
4952                self._view.ui.btn_pred_mono_back,
4953                self._view.ui.btn_pred_mono_next,
4954                self._view.ui.lbl_pred_mono_seq_name,
4955                self._view.ui.txt_pred_mono_seq_name,
4956                self._view.ui.lbl_pred_mono_seq_name_status,
4957                self._view.ui.btn_pred_mono_back_2,
4958                self._view.ui.btn_pred_mono_add_protein,
4959                self._view.ui.lbl_pred_mono_advanced_config,
4960                self._view.ui.btn_pred_mono_advanced_config,
4961                self._view.ui.btn_pred_mono_predict,
4962            ]
4963            gui_utils.show_gui_elements(gui_elements_to_show)
4964            gui_utils.hide_gui_elements(gui_elements_to_hide)
4965        else:
4966            self._view.ui.btn_pred_mono_predict.setEnabled(True)

Checks if the table proteins to predict is empty.

def display_local_pred_multi(self) -> None:
4983    def display_local_pred_multi(self) -> None:
4984        """Displays the local prediction multimer page."""
4985        # checks internet connection
4986        if not tools.check_internet_connectivity():
4987            gui_utils.no_internet_dialog()
4988            return
4989
4990        gui_elements_to_show = [
4991            self._view.ui.lbl_pred_multi_prot_to_predict,
4992            self._view.ui.table_pred_multi_prot_to_predict,
4993            self._view.ui.btn_pred_multi_prot_to_predict_add,
4994        ]
4995        gui_elements_to_hide = [
4996            self._view.ui.btn_pred_multi_prot_to_predict_remove,
4997            self._view.ui.lbl_pred_multi_prot_name_status,
4998            self._view.ui.btn_pred_multi_back,
4999            self._view.ui.btn_pred_multi_next,
5000            self._view.ui.lbl_pred_multi_prot_name,
5001            self._view.ui.txt_pred_multi_prot_name,
5002            self._view.ui.lbl_pred_multi_prot_seq,
5003            self._view.ui.txt_pred_multi_prot_seq,
5004            self._view.ui.lbl_pred_multi_prot_seq_status,
5005            self._view.ui.lbl_pred_multi_prot_seq_add,
5006            self._view.ui.btn_pred_multi_prot_seq_add,
5007            self._view.ui.lbl_pred_multi_prot_seq_overview,
5008            self._view.ui.list_pred_multi_prot_seq_overview,
5009            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5010            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5011            self._view.ui.btn_pred_multi_back_2,
5012            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5013            self._view.ui.lbl_pred_multi_advanced_config,
5014            self._view.ui.btn_pred_multi_advanced_config,
5015            self._view.ui.btn_pred_multi_predict,
5016        ]
5017        for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1, -1, -1):
5018            self._view.ui.table_pred_multi_prot_to_predict.removeRow(i)
5019        gui_utils.show_gui_elements(gui_elements_to_show)
5020        gui_utils.hide_gui_elements(gui_elements_to_hide)
5021        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 20, "Local Multimer Prediction")
5022        self.last_sidebar_button = styles.color_sidebar_buttons(
5023            self.last_sidebar_button,
5024            self._view.ui.btn_pred_local_multimer_page,
5025        )

Displays the local prediction multimer page.

def local_pred_multi_validate_protein_name(self) -> None:
5027    def local_pred_multi_validate_protein_name(self) -> None:
5028        """Validates the input of the protein name in real-time."""
5029        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5030            self._view.ui.txt_pred_multi_prot_name.text(),
5031            self._view.ui.table_pred_multi_prot_to_predict,
5032        ):
5033            self._view.ui.lbl_pred_multi_prot_name_status.setText("Protein name already used.")
5034            self._view.ui.btn_pred_multi_next.setEnabled(False)
5035            styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5036        else:
5037            self._view.ui.btn_pred_multi_next.setEnabled(True)
5038            tools.validate_protein_name(
5039                self._view.ui.txt_pred_multi_prot_name,
5040                self._view.ui.lbl_pred_multi_prot_name_status,
5041                self._view.ui.btn_pred_multi_next,
5042            )

Validates the input of the protein name in real-time.

def local_pred_multi_validate_protein_sequence(self) -> None:
5044    def local_pred_multi_validate_protein_sequence(self) -> None:
5045        """Validates the input of the protein sequence in real-time."""
5046        tools.validate_protein_sequence(
5047            self._view.ui.txt_pred_multi_prot_seq,
5048            self._view.ui.lbl_pred_multi_prot_seq_status,
5049            self._view.ui.btn_pred_multi_prot_seq_add,
5050        )

Validates the input of the protein sequence in real-time.

def local_pred_multi_check_if_table_is_empty(self) -> None:
5052    def local_pred_multi_check_if_table_is_empty(self) -> None:
5053        """Checks if the table proteins to predict is empty."""
5054        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() == 0:
5055            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
5056            self._view.ui.btn_pred_multi_predict.setEnabled(False)
5057            gui_elements_to_show = [
5058                self._view.ui.lbl_pred_multi_prot_to_predict,
5059                self._view.ui.table_pred_multi_prot_to_predict,
5060                self._view.ui.btn_pred_multi_prot_to_predict_add,
5061            ]
5062            gui_elements_to_hide = [
5063                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5064                self._view.ui.lbl_pred_multi_prot_name_status,
5065                self._view.ui.btn_pred_multi_back,
5066                self._view.ui.btn_pred_multi_next,
5067                self._view.ui.lbl_pred_multi_prot_name,
5068                self._view.ui.txt_pred_multi_prot_name,
5069                self._view.ui.lbl_pred_multi_prot_seq,
5070                self._view.ui.txt_pred_multi_prot_seq,
5071                self._view.ui.lbl_pred_multi_prot_seq_status,
5072                self._view.ui.lbl_pred_multi_prot_seq_add,
5073                self._view.ui.btn_pred_multi_prot_seq_add,
5074                self._view.ui.lbl_pred_multi_prot_seq_overview,
5075                self._view.ui.list_pred_multi_prot_seq_overview,
5076                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5077                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5078                self._view.ui.btn_pred_multi_back_2,
5079                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5080                self._view.ui.lbl_pred_multi_advanced_config,
5081                self._view.ui.btn_pred_multi_advanced_config,
5082                self._view.ui.btn_pred_multi_predict,
5083            ]
5084            gui_utils.show_gui_elements(gui_elements_to_show)
5085            gui_utils.hide_gui_elements(gui_elements_to_hide)
5086            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5087        else:
5088            self._view.ui.btn_pred_multi_predict.setEnabled(True)
5089            gui_elements_to_show = [
5090                self._view.ui.lbl_pred_multi_prot_to_predict,
5091                self._view.ui.table_pred_multi_prot_to_predict,
5092                self._view.ui.btn_pred_multi_prot_to_predict_add,
5093                self._view.ui.btn_pred_multi_prot_to_predict_remove,
5094                self._view.ui.lbl_pred_multi_advanced_config,
5095                self._view.ui.btn_pred_multi_advanced_config,
5096                self._view.ui.btn_pred_multi_predict,
5097            ]
5098            gui_elements_to_hide = [
5099                self._view.ui.lbl_pred_multi_prot_name_status,
5100                self._view.ui.btn_pred_multi_back,
5101                self._view.ui.btn_pred_multi_next,
5102                self._view.ui.lbl_pred_multi_prot_name,
5103                self._view.ui.txt_pred_multi_prot_name,
5104                self._view.ui.lbl_pred_multi_prot_seq,
5105                self._view.ui.txt_pred_multi_prot_seq,
5106                self._view.ui.lbl_pred_multi_prot_seq_status,
5107                self._view.ui.lbl_pred_multi_prot_seq_add,
5108                self._view.ui.btn_pred_multi_prot_seq_add,
5109                self._view.ui.lbl_pred_multi_prot_seq_overview,
5110                self._view.ui.list_pred_multi_prot_seq_overview,
5111                self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5112                self._view.ui.lbl_pred_multi_prot_to_predict_2,
5113                self._view.ui.btn_pred_multi_back_2,
5114                self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5115            ]
5116            gui_utils.show_gui_elements(gui_elements_to_show)
5117            gui_utils.hide_gui_elements(gui_elements_to_hide)
5118            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)

Checks if the table proteins to predict is empty.

def local_pred_multi_add_sequence_to_list(self) -> None:
5120    def local_pred_multi_add_sequence_to_list(self) -> None:
5121        """Adds the entered sequence to the list of sequences of the protein."""
5122        self._view.ui.list_pred_multi_prot_seq_overview.addItem(
5123            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_multi_prot_seq.toPlainText()),
5124        )
5125        self.local_pred_multi_check_if_list_is_empty()

Adds the entered sequence to the list of sequences of the protein.

def local_pred_multi_remove_sequence_to_list(self) -> None:
5127    def local_pred_multi_remove_sequence_to_list(self) -> None:
5128        """Removes the entered sequence to the list of sequences of the protein."""
5129        self._view.ui.list_pred_multi_prot_seq_overview.takeItem(
5130            self._view.ui.list_pred_multi_prot_seq_overview.currentRow(),
5131        )
5132        self.local_pred_multi_check_if_list_is_empty()
5133        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)

Removes the entered sequence to the list of sequences of the protein.

def local_pred_multi_check_if_list_is_empty(self) -> None:
5135    def local_pred_multi_check_if_list_is_empty(self) -> None:
5136        """Checks if the list of sequences of the protein is empty."""
5137        if self._view.ui.list_pred_multi_prot_seq_overview.count() == 0:
5138            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5139        else:
5140            self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(True)

Checks if the list of sequences of the protein is empty.

def local_pred_multi_add(self) -> None:
5142    def local_pred_multi_add(self) -> None:
5143        """Shows the gui elements for the protein name."""
5144        gui_elements_to_show = [
5145            self._view.ui.lbl_pred_multi_prot_to_predict,
5146            self._view.ui.table_pred_multi_prot_to_predict,
5147            self._view.ui.lbl_pred_multi_prot_name,
5148            self._view.ui.txt_pred_multi_prot_name,
5149            self._view.ui.lbl_pred_multi_prot_name_status,
5150            self._view.ui.btn_pred_multi_back,
5151            self._view.ui.btn_pred_multi_next,
5152        ]
5153        gui_elements_to_hide = [
5154            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5155            self._view.ui.btn_pred_multi_prot_to_predict_add,
5156            self._view.ui.lbl_pred_multi_prot_seq,
5157            self._view.ui.txt_pred_multi_prot_seq,
5158            self._view.ui.lbl_pred_multi_prot_seq_status,
5159            self._view.ui.lbl_pred_multi_prot_seq_add,
5160            self._view.ui.btn_pred_multi_prot_seq_add,
5161            self._view.ui.lbl_pred_multi_prot_seq_overview,
5162            self._view.ui.list_pred_multi_prot_seq_overview,
5163            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5164            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5165            self._view.ui.btn_pred_multi_back_2,
5166            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5167            self._view.ui.lbl_pred_multi_advanced_config,
5168            self._view.ui.btn_pred_multi_advanced_config,
5169            self._view.ui.btn_pred_multi_predict,
5170        ]
5171        gui_utils.show_gui_elements(gui_elements_to_show)
5172        gui_utils.hide_gui_elements(gui_elements_to_hide)
5173        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5174        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5175        self._view.ui.btn_pred_multi_next.setEnabled(False)
5176        self._view.ui.txt_pred_multi_prot_name.clear()
5177        styles.color_button_not_ready(self._view.ui.btn_pred_multi_next)
5178        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5179            try:
5180                self._view.ui.table_pred_multi_prot_to_predict.currentItem().setSelected(False)
5181            except AttributeError:
5182                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")

Shows the gui elements for the protein name.

def local_pred_multi_back(self) -> None:
5184    def local_pred_multi_back(self) -> None:
5185        """Hides the gui elements for the protein name."""
5186        gui_elements_to_show = [
5187            self._view.ui.lbl_pred_multi_prot_to_predict,
5188            self._view.ui.table_pred_multi_prot_to_predict,
5189            self._view.ui.btn_pred_multi_prot_to_predict_add,
5190        ]
5191        gui_elements_to_hide = [
5192            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5193            self._view.ui.lbl_pred_multi_prot_name,
5194            self._view.ui.txt_pred_multi_prot_name,
5195            self._view.ui.lbl_pred_multi_prot_name_status,
5196            self._view.ui.btn_pred_multi_back,
5197            self._view.ui.btn_pred_multi_next,
5198            self._view.ui.lbl_pred_multi_prot_seq,
5199            self._view.ui.txt_pred_multi_prot_seq,
5200            self._view.ui.lbl_pred_multi_prot_seq_status,
5201            self._view.ui.lbl_pred_multi_prot_seq_add,
5202            self._view.ui.btn_pred_multi_prot_seq_add,
5203            self._view.ui.lbl_pred_multi_prot_seq_overview,
5204            self._view.ui.list_pred_multi_prot_seq_overview,
5205            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5206            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5207            self._view.ui.btn_pred_multi_back_2,
5208            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5209            self._view.ui.lbl_pred_multi_advanced_config,
5210            self._view.ui.btn_pred_multi_advanced_config,
5211            self._view.ui.btn_pred_multi_predict,
5212        ]
5213        gui_utils.show_gui_elements(gui_elements_to_show)
5214        gui_utils.hide_gui_elements(gui_elements_to_hide)
5215        self.local_pred_multi_check_if_table_is_empty()

Hides the gui elements for the protein name.

def local_pred_multi_next(self) -> None:
5217    def local_pred_multi_next(self) -> None:
5218        """Shows the gui elements for the protein sequence."""
5219        gui_elements_to_show = [
5220            self._view.ui.lbl_pred_multi_prot_to_predict,
5221            self._view.ui.table_pred_multi_prot_to_predict,
5222            self._view.ui.lbl_pred_multi_prot_name,
5223            self._view.ui.txt_pred_multi_prot_name,
5224            self._view.ui.lbl_pred_multi_prot_seq,
5225            self._view.ui.txt_pred_multi_prot_seq,
5226            self._view.ui.lbl_pred_multi_prot_seq_status,
5227            self._view.ui.lbl_pred_multi_prot_seq_add,
5228            self._view.ui.btn_pred_multi_prot_seq_add,
5229            self._view.ui.lbl_pred_multi_prot_seq_overview,
5230            self._view.ui.list_pred_multi_prot_seq_overview,
5231            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5232            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5233            self._view.ui.btn_pred_multi_back_2,
5234            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5235        ]
5236        gui_elements_to_hide = [
5237            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5238            self._view.ui.btn_pred_multi_prot_to_predict_add,
5239            self._view.ui.lbl_pred_multi_prot_name_status,
5240            self._view.ui.btn_pred_multi_back,
5241            self._view.ui.btn_pred_multi_next,
5242            self._view.ui.lbl_pred_multi_advanced_config,
5243            self._view.ui.btn_pred_multi_advanced_config,
5244            self._view.ui.btn_pred_multi_predict,
5245        ]
5246        gui_utils.show_gui_elements(gui_elements_to_show)
5247        gui_utils.hide_gui_elements(gui_elements_to_hide)
5248        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)
5249        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5250        self._view.ui.txt_pred_multi_prot_seq.clear()
5251        self._view.ui.list_pred_multi_prot_seq_overview.clear()
5252        self._view.ui.btn_pred_multi_prot_to_predict_add_2.setEnabled(False)
5253        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(False)
5254        styles.color_button_not_ready(self._view.ui.btn_pred_multi_prot_to_predict_add_2)

Shows the gui elements for the protein sequence.

def local_pred_multi_back_2(self) -> None:
5256    def local_pred_multi_back_2(self) -> None:
5257        """Hides the gui elements for the protein sequence."""
5258        gui_elements_to_show = [
5259            self._view.ui.lbl_pred_multi_prot_to_predict,
5260            self._view.ui.table_pred_multi_prot_to_predict,
5261            self._view.ui.lbl_pred_multi_prot_name_status,
5262            self._view.ui.btn_pred_multi_back,
5263            self._view.ui.btn_pred_multi_next,
5264            self._view.ui.lbl_pred_multi_prot_name,
5265            self._view.ui.txt_pred_multi_prot_name,
5266        ]
5267        gui_elements_to_hide = [
5268            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5269            self._view.ui.btn_pred_multi_prot_to_predict_add,
5270            self._view.ui.lbl_pred_multi_prot_seq,
5271            self._view.ui.txt_pred_multi_prot_seq,
5272            self._view.ui.lbl_pred_multi_prot_seq_status,
5273            self._view.ui.lbl_pred_multi_prot_seq_add,
5274            self._view.ui.btn_pred_multi_prot_seq_add,
5275            self._view.ui.lbl_pred_multi_prot_seq_overview,
5276            self._view.ui.list_pred_multi_prot_seq_overview,
5277            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5278            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5279            self._view.ui.btn_pred_multi_back_2,
5280            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5281            self._view.ui.lbl_pred_multi_advanced_config,
5282            self._view.ui.btn_pred_multi_advanced_config,
5283            self._view.ui.btn_pred_multi_predict,
5284        ]
5285        gui_utils.show_gui_elements(gui_elements_to_show)
5286        gui_utils.hide_gui_elements(gui_elements_to_hide)
5287        gui_utils.enable_text_box(self._view.ui.txt_pred_multi_prot_name, self._view.ui.lbl_pred_multi_prot_name)
5288        gui_utils.disable_text_box(self._view.ui.txt_pred_multi_prot_seq, self._view.ui.lbl_pred_multi_prot_seq)

Hides the gui elements for the protein sequence.

def local_pred_multi_prot_seq_overview_item_changed(self) -> None:
5290    def local_pred_multi_prot_seq_overview_item_changed(self) -> None:
5291        """Enables the remove button of the list sequences of the protein."""
5292        self._view.ui.btn_pred_multi_prot_seq_overview_remove.setEnabled(True)

Enables the remove button of the list sequences of the protein.

def local_pred_multi_prot_to_predict_item_changed(self) -> None:
5294    def local_pred_multi_prot_to_predict_item_changed(self) -> None:
5295        """Enables the remove button of the table proteins to predict."""
5296        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(True)

Enables the remove button of the table proteins to predict.

def local_pred_multi_prot_to_predict_add_2(self) -> None:
5298    def local_pred_multi_prot_to_predict_add_2(self) -> None:
5299        """Adds the protein to the list of proteins to predict."""
5300        for i in range(self._view.ui.list_pred_multi_prot_seq_overview.count()):
5301            self._view.ui.table_pred_multi_prot_to_predict.setRowCount(
5302                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5303            )
5304            self._view.ui.table_pred_multi_prot_to_predict.insertRow(
5305                self._view.ui.table_pred_multi_prot_to_predict.rowCount() + 1,
5306            )
5307            tmp_chain_seq = (
5308                constants.chain_dict.get(i),
5309                self._view.ui.list_pred_multi_prot_seq_overview.item(i).text(),
5310            )
5311            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5312                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5313                0,
5314                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
5315            )
5316            self._view.ui.table_pred_multi_prot_to_predict.setItem(
5317                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5318                1,
5319                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
5320            )
5321            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_multi_prot_name.text())
5322            self._view.ui.table_pred_multi_prot_to_predict.setVerticalHeaderItem(
5323                self._view.ui.table_pred_multi_prot_to_predict.rowCount() - 1,
5324                name_item,
5325            )
5326        self._view.ui.table_pred_multi_prot_to_predict.resizeColumnsToContents()
5327        self.local_pred_multi_check_if_table_is_empty()
5328        gui_elements_to_show = [
5329            self._view.ui.lbl_pred_multi_prot_to_predict,
5330            self._view.ui.table_pred_multi_prot_to_predict,
5331            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5332            self._view.ui.btn_pred_multi_prot_to_predict_add,
5333            self._view.ui.lbl_pred_multi_advanced_config,
5334            self._view.ui.btn_pred_multi_advanced_config,
5335            self._view.ui.btn_pred_multi_predict,
5336        ]
5337        gui_elements_to_hide = [
5338            self._view.ui.lbl_pred_multi_prot_name_status,
5339            self._view.ui.btn_pred_multi_back,
5340            self._view.ui.btn_pred_multi_next,
5341            self._view.ui.lbl_pred_multi_prot_name,
5342            self._view.ui.txt_pred_multi_prot_name,
5343            self._view.ui.lbl_pred_multi_prot_seq,
5344            self._view.ui.txt_pred_multi_prot_seq,
5345            self._view.ui.lbl_pred_multi_prot_seq_status,
5346            self._view.ui.lbl_pred_multi_prot_seq_add,
5347            self._view.ui.btn_pred_multi_prot_seq_add,
5348            self._view.ui.lbl_pred_multi_prot_seq_overview,
5349            self._view.ui.list_pred_multi_prot_seq_overview,
5350            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5351            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5352            self._view.ui.btn_pred_multi_back_2,
5353            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5354        ]
5355        gui_utils.show_gui_elements(gui_elements_to_show)
5356        gui_utils.hide_gui_elements(gui_elements_to_hide)
5357        self._init_local_pred_multi_page()
5358        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)

Adds the protein to the list of proteins to predict.

def local_pred_multi_remove(self) -> None:
5360    def local_pred_multi_remove(self) -> None:
5361        """Removes the selected protein from the list of proteins to predict."""
5362        self._view.ui.table_pred_multi_prot_to_predict.removeRow(
5363            self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5364        )
5365        if self._view.ui.table_pred_multi_prot_to_predict.rowCount() > 0:
5366            prot_name = self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(
5367                self._view.ui.table_pred_multi_prot_to_predict.currentRow(),
5368            ).text()
5369            for i in range(self._view.ui.table_pred_multi_prot_to_predict.rowCount()):
5370                if self._view.ui.table_pred_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
5371                    self._view.ui.table_pred_multi_prot_to_predict.setItem(
5372                        i,
5373                        0,
5374                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
5375                    )
5376        self.local_pred_multi_check_if_table_is_empty()
5377        gui_elements_to_show = [
5378            self._view.ui.lbl_pred_multi_prot_to_predict,
5379            self._view.ui.table_pred_multi_prot_to_predict,
5380            self._view.ui.btn_pred_multi_prot_to_predict_remove,
5381            self._view.ui.btn_pred_multi_prot_to_predict_add,
5382            self._view.ui.lbl_pred_multi_advanced_config,
5383            self._view.ui.btn_pred_multi_advanced_config,
5384            self._view.ui.btn_pred_multi_predict,
5385        ]
5386        gui_elements_to_hide = [
5387            self._view.ui.lbl_pred_multi_prot_name_status,
5388            self._view.ui.btn_pred_multi_back,
5389            self._view.ui.btn_pred_multi_next,
5390            self._view.ui.lbl_pred_multi_prot_name,
5391            self._view.ui.txt_pred_multi_prot_name,
5392            self._view.ui.lbl_pred_multi_prot_seq,
5393            self._view.ui.txt_pred_multi_prot_seq,
5394            self._view.ui.lbl_pred_multi_prot_seq_status,
5395            self._view.ui.lbl_pred_multi_prot_seq_add,
5396            self._view.ui.btn_pred_multi_prot_seq_add,
5397            self._view.ui.lbl_pred_multi_prot_seq_overview,
5398            self._view.ui.list_pred_multi_prot_seq_overview,
5399            self._view.ui.btn_pred_multi_prot_seq_overview_remove,
5400            self._view.ui.lbl_pred_multi_prot_to_predict_2,
5401            self._view.ui.btn_pred_multi_back_2,
5402            self._view.ui.btn_pred_multi_prot_to_predict_add_2,
5403        ]
5404        gui_utils.show_gui_elements(gui_elements_to_show)
5405        gui_utils.hide_gui_elements(gui_elements_to_hide)
5406        self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
5407        self.local_pred_multi_check_if_table_is_empty()

Removes the selected protein from the list of proteins to predict.

def display_monomer_pred_analysis(self) -> None:
5433    def display_monomer_pred_analysis(self) -> None:
5434        """Displays the monomer prediction + analysis page."""
5435        # checks internet connection
5436        if not tools.check_internet_connectivity():
5437            gui_utils.no_internet_dialog()
5438            return
5439
5440        self._init_mono_pred_analysis_page()
5441        self._view.ui.table_pred_analysis_mono_prot_to_predict.clear()
5442        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5443            0,
5444            QtWidgets.QTableWidgetItem("Chain"),
5445        )
5446        self._view.ui.table_pred_analysis_mono_prot_to_predict.setHorizontalHeaderItem(
5447            1,
5448            QtWidgets.QTableWidgetItem("Sequence"),
5449        )
5450        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5451        gui_elements_to_show = [
5452            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5453            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5454            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5455        ]
5456        gui_elements_to_hide = [
5457            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5458            self._view.ui.lbl_pred_analysis_mono_prot_name,
5459            self._view.ui.txt_pred_analysis_mono_prot_name,
5460            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5461            self._view.ui.btn_pred_analysis_mono_back,
5462            self._view.ui.btn_pred_analysis_mono_next,
5463            self._view.ui.lbl_pred_analysis_mono_seq_name,
5464            self._view.ui.txt_pred_analysis_mono_seq_name,
5465            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5466            self._view.ui.btn_pred_analysis_mono_back_2,
5467            self._view.ui.btn_pred_analysis_mono_add_protein,
5468            self._view.ui.lbl_pred_mono_advanced_config_2,
5469            self._view.ui.btn_pred_mono_advanced_config_2,
5470            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5471            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5472        ]
5473        gui_utils.show_gui_elements(gui_elements_to_show)
5474        gui_utils.hide_gui_elements(gui_elements_to_hide)
5475        if self._view.ui.tabWidget.currentIndex() == 1:
5476            self._view.ui.tabWidget.setCurrentIndex(0)
5477        self._view.ui.tabWidget.setTabEnabled(1, False)
5478        self._view.ui.tabWidget.setTabEnabled(0, True)
5479        tools.switch_page(
5480            self._view.ui.stackedWidget,
5481            self._view.ui.lbl_page_title,
5482            21,
5483            "Monomer Prediction + Analysis",
5484        )
5485        self.last_sidebar_button = styles.color_sidebar_buttons(
5486            self.last_sidebar_button,
5487            self._view.ui.btn_pred_analysis_monomer_page,
5488        )
5489        self._view.ui.table_pred_analysis_mono_prot_to_predict.setEnabled(True)

Displays the monomer prediction + analysis page.

def mono_pred_analysis_validate_protein_name(self) -> None:
5494    def mono_pred_analysis_validate_protein_name(self) -> None:
5495        """Validates the input of the protein name in real-time."""
5496        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
5497            self._view.ui.txt_pred_analysis_mono_prot_name.text(),
5498            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5499        ):
5500            self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("Protein name already used.")
5501            self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5502            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5503        else:
5504            self._view.ui.btn_pred_analysis_mono_next.setEnabled(True)
5505            tools.validate_protein_name(
5506                self._view.ui.txt_pred_analysis_mono_prot_name,
5507                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5508                self._view.ui.btn_pred_analysis_mono_next,
5509            )

Validates the input of the protein name in real-time.

def mono_pred_analysis_validate_protein_sequence(self) -> None:
5511    def mono_pred_analysis_validate_protein_sequence(self) -> None:
5512        """Validates the input of the protein sequence in real-time."""
5513        tools.validate_protein_sequence(
5514            self._view.ui.txt_pred_analysis_mono_seq_name,
5515            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5516            self._view.ui.btn_pred_analysis_mono_add_protein,
5517        )

Validates the input of the protein sequence in real-time.

def mono_pred_analysis_check_if_table_is_empty(self) -> None:
5519    def mono_pred_analysis_check_if_table_is_empty(self) -> None:
5520        """Checks if the table proteins to predict is empty."""
5521        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() == 0:
5522            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_go_analysis_setup)
5523            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(False)
5524            gui_elements_to_show = [
5525                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5526                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5527                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5528            ]
5529            gui_elements_to_hide = [
5530                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5531                self._view.ui.lbl_pred_analysis_mono_prot_name,
5532                self._view.ui.txt_pred_analysis_mono_prot_name,
5533                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5534                self._view.ui.btn_pred_analysis_mono_back,
5535                self._view.ui.btn_pred_analysis_mono_next,
5536                self._view.ui.lbl_pred_analysis_mono_seq_name,
5537                self._view.ui.txt_pred_analysis_mono_seq_name,
5538                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5539                self._view.ui.btn_pred_analysis_mono_back_2,
5540                self._view.ui.btn_pred_analysis_mono_add_protein,
5541                self._view.ui.lbl_pred_mono_advanced_config_2,
5542                self._view.ui.btn_pred_mono_advanced_config_2,
5543                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5544                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5545            ]
5546            gui_utils.show_gui_elements(gui_elements_to_show)
5547            gui_utils.hide_gui_elements(gui_elements_to_hide)
5548        else:
5549            gui_elements_to_show = [
5550                self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5551                self._view.ui.table_pred_analysis_mono_prot_to_predict,
5552                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5553                self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5554                self._view.ui.lbl_pred_mono_advanced_config_2,
5555                self._view.ui.btn_pred_mono_advanced_config_2,
5556                self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5557                self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5558            ]
5559            gui_elements_to_hide = [
5560                self._view.ui.lbl_pred_analysis_mono_prot_name,
5561                self._view.ui.txt_pred_analysis_mono_prot_name,
5562                self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5563                self._view.ui.btn_pred_analysis_mono_back,
5564                self._view.ui.btn_pred_analysis_mono_next,
5565                self._view.ui.lbl_pred_analysis_mono_seq_name,
5566                self._view.ui.txt_pred_analysis_mono_seq_name,
5567                self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5568                self._view.ui.btn_pred_analysis_mono_back_2,
5569                self._view.ui.btn_pred_analysis_mono_add_protein,
5570            ]
5571            gui_utils.show_gui_elements(gui_elements_to_show)
5572            gui_utils.hide_gui_elements(gui_elements_to_hide)
5573            self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)

Checks if the table proteins to predict is empty.

def setup_defaults_monomer_prediction_analysis(self) -> None:
5575    def setup_defaults_monomer_prediction_analysis(self) -> None:
5576        """Sets up default values for the prediction tab."""
5577        # clears everything
5578        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5579        self._view.ui.txt_pred_analysis_mono_seq_name.clear()
5580        # sets up defaults: Prediction
5581        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5582        self._view.ui.btn_pred_analysis_mono_add_protein.setEnabled(False)
5583        self._view.ui.lbl_pred_analysis_mono_prot_name_status.setText("")
5584        self._view.ui.lbl_pred_analysis_mono_seq_name_status.setText("")

Sets up default values for the prediction tab.

def mono_pred_analysis_add_seq_to_predict(self) -> None:
5586    def mono_pred_analysis_add_seq_to_predict(self) -> None:
5587        """Shows the gui elements for the protein name."""
5588        gui_elements_to_show = [
5589            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5590            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5591            self._view.ui.lbl_pred_analysis_mono_prot_name,
5592            self._view.ui.txt_pred_analysis_mono_prot_name,
5593            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5594            self._view.ui.btn_pred_analysis_mono_back,
5595            self._view.ui.btn_pred_analysis_mono_next,
5596        ]
5597        gui_utils.enable_text_box(
5598            self._view.ui.txt_pred_analysis_mono_prot_name,
5599            self._view.ui.lbl_pred_analysis_mono_prot_name,
5600        )
5601        gui_elements_to_hide = [
5602            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5603            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5604            self._view.ui.lbl_pred_analysis_mono_seq_name,
5605            self._view.ui.txt_pred_analysis_mono_seq_name,
5606            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5607            self._view.ui.btn_pred_analysis_mono_back_2,
5608            self._view.ui.btn_pred_analysis_mono_add_protein,
5609            self._view.ui.lbl_pred_mono_advanced_config_2,
5610            self._view.ui.btn_pred_mono_advanced_config_2,
5611            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5612            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5613        ]
5614        gui_utils.disable_text_box(
5615            self._view.ui.txt_pred_analysis_mono_seq_name,
5616            self._view.ui.lbl_pred_analysis_mono_seq_name,
5617        )
5618        gui_utils.show_gui_elements(gui_elements_to_show)
5619        gui_utils.hide_gui_elements(gui_elements_to_hide)
5620        self._view.ui.btn_pred_analysis_mono_next.setEnabled(False)
5621        self._view.ui.txt_pred_analysis_mono_prot_name.clear()
5622        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next)
5623        if self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() > 0:
5624            try:
5625                self._view.ui.table_pred_analysis_mono_prot_to_predict.currentItem().setSelected(False)
5626            except AttributeError:
5627                constants.PYSSA_LOGGER.debug("No selection on Local Monomer Prediction in overview table.")

Shows the gui elements for the protein name.

def mono_pred_analysis_back(self) -> None:
5629    def mono_pred_analysis_back(self) -> None:
5630        """Hides the gui elements for the protein name."""
5631        gui_elements_to_show = [
5632            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5633            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5634            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5635            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5636        ]
5637        gui_elements_to_hide = [
5638            self._view.ui.lbl_pred_analysis_mono_prot_name,
5639            self._view.ui.txt_pred_analysis_mono_prot_name,
5640            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5641            self._view.ui.btn_pred_analysis_mono_back,
5642            self._view.ui.btn_pred_analysis_mono_next,
5643            self._view.ui.lbl_pred_analysis_mono_seq_name,
5644            self._view.ui.txt_pred_analysis_mono_seq_name,
5645            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5646            self._view.ui.btn_pred_analysis_mono_back_2,
5647            self._view.ui.btn_pred_analysis_mono_add_protein,
5648            self._view.ui.lbl_pred_mono_advanced_config_2,
5649            self._view.ui.btn_pred_mono_advanced_config_2,
5650            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5651            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5652        ]
5653        gui_utils.show_gui_elements(gui_elements_to_show)
5654        gui_utils.hide_gui_elements(gui_elements_to_hide)
5655        self.mono_pred_analysis_check_if_table_is_empty()
5656        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)

Hides the gui elements for the protein name.

def mono_pred_analysis_next(self) -> None:
5658    def mono_pred_analysis_next(self) -> None:
5659        """Shows the gui elements for the protein sequence."""
5660        gui_elements_to_show = [
5661            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5662            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5663            self._view.ui.lbl_pred_analysis_mono_prot_name,
5664            self._view.ui.txt_pred_analysis_mono_prot_name,
5665            self._view.ui.lbl_pred_analysis_mono_seq_name,
5666            self._view.ui.txt_pred_analysis_mono_seq_name,
5667            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5668            self._view.ui.btn_pred_analysis_mono_back_2,
5669            self._view.ui.btn_pred_analysis_mono_add_protein,
5670        ]
5671        gui_utils.enable_text_box(
5672            self._view.ui.txt_pred_analysis_mono_seq_name,
5673            self._view.ui.lbl_pred_analysis_mono_seq_name,
5674        )
5675        gui_elements_to_hide = [
5676            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5677            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5678            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5679            self._view.ui.btn_pred_analysis_mono_back,
5680            self._view.ui.btn_pred_analysis_mono_next,
5681            self._view.ui.lbl_pred_mono_advanced_config_2,
5682            self._view.ui.btn_pred_mono_advanced_config_2,
5683            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5684            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5685        ]
5686        gui_utils.disable_text_box(
5687            self._view.ui.txt_pred_analysis_mono_prot_name,
5688            self._view.ui.lbl_pred_analysis_mono_prot_name,
5689        )
5690        gui_utils.show_gui_elements(gui_elements_to_show)
5691        gui_utils.hide_gui_elements(gui_elements_to_hide)
5692        self._view.ui.txt_pred_analysis_mono_seq_name.clear()

Shows the gui elements for the protein sequence.

def mono_pred_analysis_back_2(self) -> None:
5694    def mono_pred_analysis_back_2(self) -> None:
5695        """Hides the gui elements for the protein sequence."""
5696        gui_elements_to_show = [
5697            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5698            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5699            self._view.ui.lbl_pred_analysis_mono_prot_name,
5700            self._view.ui.txt_pred_analysis_mono_prot_name,
5701            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5702            self._view.ui.btn_pred_analysis_mono_back,
5703            self._view.ui.btn_pred_analysis_mono_next,
5704        ]
5705        gui_elements_to_hide = [
5706            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5707            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5708            self._view.ui.lbl_pred_analysis_mono_seq_name,
5709            self._view.ui.txt_pred_analysis_mono_seq_name,
5710            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5711            self._view.ui.btn_pred_analysis_mono_back_2,
5712            self._view.ui.btn_pred_analysis_mono_add_protein,
5713            self._view.ui.lbl_pred_mono_advanced_config_2,
5714            self._view.ui.btn_pred_mono_advanced_config_2,
5715            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5716            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5717        ]
5718        gui_utils.enable_text_box(
5719            self._view.ui.txt_pred_analysis_mono_prot_name,
5720            self._view.ui.lbl_pred_analysis_mono_prot_name,
5721        )
5722        gui_utils.disable_text_box(
5723            self._view.ui.txt_pred_analysis_mono_seq_name,
5724            self._view.ui.lbl_pred_analysis_mono_seq_name,
5725        )
5726        gui_utils.show_gui_elements(gui_elements_to_show)
5727        gui_utils.hide_gui_elements(gui_elements_to_hide)

Hides the gui elements for the protein sequence.

def mono_pred_analysis_add_protein(self) -> None:
5729    def mono_pred_analysis_add_protein(self) -> None:
5730        """Adds the protein to the list of proteins to predict."""
5731        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5732            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5733        )
5734        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5735            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5736        )
5737        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5738            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5739            0,
5740            QtWidgets.QTableWidgetItem("A"),
5741        )
5742        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5743            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5744            1,
5745            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5746        )
5747        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5748            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5749            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5750        )
5751        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5752        self.mono_pred_analysis_check_if_table_is_empty()
5753        gui_elements_to_show = [
5754            self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
5755            self._view.ui.table_pred_analysis_mono_prot_to_predict,
5756            self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
5757            self._view.ui.btn_pred_analysis_mono_seq_to_predict,
5758            self._view.ui.lbl_pred_mono_advanced_config_2,
5759            self._view.ui.btn_pred_mono_advanced_config_2,
5760            self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
5761            self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
5762        ]
5763        gui_utils.enable_text_box(
5764            self._view.ui.txt_pred_analysis_mono_prot_name,
5765            self._view.ui.lbl_pred_analysis_mono_prot_name,
5766        )
5767        gui_elements_to_hide = [
5768            self._view.ui.lbl_pred_analysis_mono_prot_name,
5769            self._view.ui.txt_pred_analysis_mono_prot_name,
5770            self._view.ui.lbl_pred_analysis_mono_prot_name_status,
5771            self._view.ui.btn_pred_analysis_mono_back,
5772            self._view.ui.btn_pred_analysis_mono_next,
5773            self._view.ui.lbl_pred_analysis_mono_seq_name,
5774            self._view.ui.txt_pred_analysis_mono_seq_name,
5775            self._view.ui.lbl_pred_analysis_mono_seq_name_status,
5776            self._view.ui.btn_pred_analysis_mono_back_2,
5777            self._view.ui.btn_pred_analysis_mono_add_protein,
5778        ]
5779        gui_utils.show_gui_elements(gui_elements_to_show)
5780        gui_utils.hide_gui_elements(gui_elements_to_hide)
5781        self._view.ui.btn_pred_analysis_mono_go_analysis_setup.setEnabled(True)
5782        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
5783        self.setup_defaults_monomer_prediction()

Adds the protein to the list of proteins to predict.

def mono_pred_analysis_prediction_overview_item_clicked(self) -> None:
5785    def mono_pred_analysis_prediction_overview_item_clicked(self) -> None:
5786        """Enables the remove button."""
5787        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(True)

Enables the remove button.

def mono_pred_analysis_add_protein_to_predict(self) -> None:
5789    def mono_pred_analysis_add_protein_to_predict(self) -> None:
5790        """Needs to be removed."""
5791        self._view.ui.table_pred_analysis_mono_prot_to_predict.setRowCount(
5792            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5793        )
5794        self._view.ui.table_pred_analysis_mono_prot_to_predict.insertRow(
5795            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() + 1,
5796        )
5797        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5798            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5799            0,
5800            QtWidgets.QTableWidgetItem("A"),
5801        )
5802        self._view.ui.table_pred_analysis_mono_prot_to_predict.setItem(
5803            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5804            1,
5805            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_seq_name.toPlainText()),
5806        )
5807        self._view.ui.table_pred_analysis_mono_prot_to_predict.setVerticalHeaderItem(
5808            self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount() - 1,
5809            QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_mono_prot_name.text()),
5810        )
5811        self._view.ui.table_pred_analysis_mono_prot_to_predict.resizeColumnsToContents()
5812        self.mono_pred_analysis_check_if_table_is_empty()
5813        self.setup_defaults_monomer_prediction_analysis()

Needs to be removed.

def mono_pred_analysis_remove_protein_to_predict(self) -> None:
5815    def mono_pred_analysis_remove_protein_to_predict(self) -> None:
5816        """Removes the selected protein from the list of proteins to predict."""
5817        self._view.ui.table_pred_analysis_mono_prot_to_predict.removeRow(
5818            self._view.ui.table_pred_analysis_mono_prot_to_predict.currentRow(),
5819        )
5820        self.mono_pred_analysis_check_if_table_is_empty()
5821        self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)

Removes the selected protein from the list of proteins to predict.

def mono_pred_analysis_structure_analysis_add(self) -> None:
5826    def mono_pred_analysis_structure_analysis_add(self) -> None:
5827        """Shows the gui elements for the selection of the two proteins."""
5828        gui_elements_to_show = [
5829            self._view.ui.lbl_pred_analysis_mono_overview,
5830            self._view.ui.list_pred_analysis_mono_overview,
5831            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5832            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5833            self._view.ui.lbl_analysis_batch_vs_2,
5834            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5835            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5836            self._view.ui.btn_pred_analysis_mono_back_3,
5837            self._view.ui.btn_pred_analysis_mono_next_2,
5838        ]
5839        gui_elements_to_hide = [
5840            self._view.ui.btn_pred_analysis_mono_remove,
5841            self._view.ui.btn_pred_analysis_mono_add,
5842            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5843            self._view.ui.list_pred_analysis_mono_ref_chains,
5844            self._view.ui.btn_pred_analysis_mono_back_4,
5845            self._view.ui.btn_pred_analysis_mono_next_3,
5846            self._view.ui.lbl_pred_analysis_mono_model_chains,
5847            self._view.ui.list_pred_analysis_mono_model_chains,
5848            self._view.ui.btn_pred_analysis_mono_back_5,
5849            self._view.ui.btn_pred_analysis_mono_next_4,
5850            self._view.ui.lbl_pred_analysis_mono_images,
5851            self._view.ui.cb_pred_analysis_mono_images,
5852            self._view.ui.btn_pred_analysis_mono_start,
5853            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5854        ]
5855        gui_utils.show_gui_elements(gui_elements_to_show)
5856        gui_utils.hide_gui_elements(gui_elements_to_hide)
5857        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.clear()
5858        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.clear()
5859        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5860        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")
5861        self.fill_mono_pred_analysis_protein_boxes()
5862        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5863            try:
5864                self._view.ui.list_pred_analysis_mono_overview.currentItem().setSelected(False)
5865            except AttributeError:
5866                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")

Shows the gui elements for the selection of the two proteins.

def mono_pred_analysis_structure_analysis_back_3(self) -> None:
5868    def mono_pred_analysis_structure_analysis_back_3(self) -> None:
5869        """Hides the gui elements to select the two proteins."""
5870        gui_elements_to_show = [
5871            self._view.ui.lbl_pred_analysis_mono_overview,
5872            self._view.ui.list_pred_analysis_mono_overview,
5873            self._view.ui.btn_pred_analysis_mono_add,
5874            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5875        ]
5876        gui_elements_to_hide = [
5877            self._view.ui.btn_pred_analysis_mono_remove,
5878            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5879            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5880            self._view.ui.lbl_analysis_batch_vs_2,
5881            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5882            self._view.ui.list_pred_analysis_mono_ref_chains,
5883            self._view.ui.btn_pred_analysis_mono_back_4,
5884            self._view.ui.btn_pred_analysis_mono_next_3,
5885            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5886            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5887            self._view.ui.btn_pred_analysis_mono_back_3,
5888            self._view.ui.btn_pred_analysis_mono_next_2,
5889            self._view.ui.lbl_pred_analysis_mono_model_chains,
5890            self._view.ui.list_pred_analysis_mono_model_chains,
5891            self._view.ui.btn_pred_analysis_mono_back_5,
5892            self._view.ui.btn_pred_analysis_mono_next_4,
5893            self._view.ui.lbl_pred_analysis_mono_images,
5894            self._view.ui.cb_pred_analysis_mono_images,
5895            self._view.ui.btn_pred_analysis_mono_start,
5896        ]
5897        gui_utils.show_gui_elements(gui_elements_to_show)
5898        gui_utils.hide_gui_elements(gui_elements_to_hide)
5899        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
5900            self._view.ui.btn_pred_analysis_mono_remove.show()
5901            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
5902            self._view.ui.btn_pred_analysis_mono_start.show()
5903            self._view.ui.lbl_pred_analysis_mono_images.show()
5904            self._view.ui.cb_pred_analysis_mono_images.show()

Hides the gui elements to select the two proteins.

def mono_pred_analysis_structure_analysis_next_3(self) -> None:
5906    def mono_pred_analysis_structure_analysis_next_3(self) -> None:
5907        """Shows the gui elements to select the chains of protein 2."""
5908        gui_elements_to_show = [
5909            self._view.ui.lbl_pred_analysis_mono_overview,
5910            self._view.ui.list_pred_analysis_mono_overview,
5911            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5912            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5913            self._view.ui.lbl_analysis_batch_vs_2,
5914            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5915            self._view.ui.list_pred_analysis_mono_ref_chains,
5916            self._view.ui.lbl_pred_analysis_mono_model_chains,
5917            self._view.ui.list_pred_analysis_mono_model_chains,
5918            self._view.ui.btn_pred_analysis_mono_back_5,
5919            self._view.ui.btn_pred_analysis_mono_next_4,
5920        ]
5921        gui_elements_to_hide = [
5922            self._view.ui.btn_pred_analysis_mono_remove,
5923            self._view.ui.btn_pred_analysis_mono_add,
5924            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5925            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5926            self._view.ui.btn_pred_analysis_mono_back_3,
5927            self._view.ui.btn_pred_analysis_mono_next_2,
5928            self._view.ui.btn_pred_analysis_mono_back_4,
5929            self._view.ui.btn_pred_analysis_mono_next_3,
5930            self._view.ui.lbl_pred_analysis_mono_images,
5931            self._view.ui.cb_pred_analysis_mono_images,
5932            self._view.ui.btn_pred_analysis_mono_start,
5933            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5934        ]
5935        gui_utils.show_gui_elements(gui_elements_to_show)
5936        gui_utils.hide_gui_elements(gui_elements_to_hide)
5937        self._view.ui.list_pred_analysis_mono_model_chains.clear()
5938        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(False)
5939        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
5940
5941        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
5942            if (
5943                self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text()
5944                == self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText()
5945            ):
5946                self._view.ui.list_pred_analysis_mono_model_chains.addItem(
5947                    self._view.ui.table_pred_analysis_mono_prot_to_predict.item(i, 0).text(),
5948                )
5949        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 0:
5950            tmp_protein = self._current_project.search_protein(
5951                self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText(),
5952            )
5953            for tmp_chain in tmp_protein.chains:
5954                if tmp_chain.chain_type == "protein_chain":
5955                    self._view.ui.list_pred_analysis_mono_model_chains.addItem(tmp_chain.chain_letter)
5956        if self._view.ui.list_pred_analysis_mono_model_chains.count() == 1:
5957            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5958                f"Select chain in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5959            )
5960        else:
5961            self._view.ui.lbl_pred_analysis_mono_model_chains.setText(
5962                f"Select {len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems())} chains "
5963                f"in protein structure {self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()}.",
5964            )

Shows the gui elements to select the chains of protein 2.

def mono_pred_analysis_structure_analysis_back_4(self) -> None:
5966    def mono_pred_analysis_structure_analysis_back_4(self) -> None:
5967        """Hides the gui elements to select the chains in protein 1."""
5968        gui_elements_to_show = [
5969            self._view.ui.lbl_pred_analysis_mono_overview,
5970            self._view.ui.list_pred_analysis_mono_overview,
5971            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
5972            self._view.ui.box_pred_analysis_mono_prot_struct_1,
5973            self._view.ui.lbl_analysis_batch_vs_2,
5974            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
5975            self._view.ui.box_pred_analysis_mono_prot_struct_2,
5976            self._view.ui.btn_pred_analysis_mono_back_3,
5977            self._view.ui.btn_pred_analysis_mono_next_2,
5978            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
5979        ]
5980        gui_elements_to_hide = [
5981            self._view.ui.btn_pred_analysis_mono_remove,
5982            self._view.ui.btn_pred_analysis_mono_add,
5983            self._view.ui.lbl_pred_analysis_mono_ref_chains,
5984            self._view.ui.list_pred_analysis_mono_ref_chains,
5985            self._view.ui.btn_pred_analysis_mono_back_4,
5986            self._view.ui.btn_pred_analysis_mono_next_3,
5987            self._view.ui.lbl_pred_analysis_mono_model_chains,
5988            self._view.ui.list_pred_analysis_mono_model_chains,
5989            self._view.ui.btn_pred_analysis_mono_back_5,
5990            self._view.ui.btn_pred_analysis_mono_next_4,
5991            self._view.ui.lbl_pred_analysis_mono_images,
5992            self._view.ui.cb_pred_analysis_mono_images,
5993            self._view.ui.btn_pred_analysis_mono_start,
5994        ]
5995        gui_utils.show_gui_elements(gui_elements_to_show)
5996        gui_utils.hide_gui_elements(gui_elements_to_hide)
5997        self._view.ui.lbl_pred_analysis_mono_prot_struct_1.setText("Protein structure 1")
5998        self._view.ui.lbl_pred_analysis_mono_prot_struct_2.setText("Protein structure 2")

Hides the gui elements to select the chains in protein 1.

def mono_pred_analysis_structure_analysis_next_4(self) -> None:
6000    def mono_pred_analysis_structure_analysis_next_4(self) -> None:
6001        """Adds the protein pair to the list of protein pairs to analyze."""
6002        gui_elements_to_show = [
6003            self._view.ui.btn_pred_analysis_mono_remove,
6004            self._view.ui.btn_pred_analysis_mono_add,
6005            self._view.ui.lbl_pred_analysis_mono_overview,
6006            self._view.ui.list_pred_analysis_mono_overview,
6007            self._view.ui.lbl_pred_analysis_mono_images,
6008            self._view.ui.cb_pred_analysis_mono_images,
6009            self._view.ui.btn_pred_analysis_mono_start,
6010            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6011        ]
6012        gui_elements_to_hide = [
6013            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6014            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6015            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6016            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6017            self._view.ui.lbl_analysis_batch_vs_2,
6018            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6019            self._view.ui.list_pred_analysis_mono_ref_chains,
6020            self._view.ui.lbl_pred_analysis_mono_model_chains,
6021            self._view.ui.list_pred_analysis_mono_model_chains,
6022            self._view.ui.btn_pred_analysis_mono_back_3,
6023            self._view.ui.btn_pred_analysis_mono_next_2,
6024            self._view.ui.btn_pred_analysis_mono_back_4,
6025            self._view.ui.btn_pred_analysis_mono_next_3,
6026            self._view.ui.btn_pred_analysis_mono_back_5,
6027            self._view.ui.btn_pred_analysis_mono_next_4,
6028        ]
6029        gui_utils.show_gui_elements(gui_elements_to_show)
6030        gui_utils.hide_gui_elements(gui_elements_to_hide)
6031        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6032        prot_1_chains = []
6033        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6034            prot_1_chains.append(chain.text())
6035        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6036        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6037        prot_2_chains = []
6038        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6039            prot_2_chains.append(chain.text())
6040        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6041        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6042        item = QtWidgets.QListWidgetItem(analysis_name)
6043        self._view.ui.list_pred_analysis_mono_overview.addItem(item)
6044        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)

Adds the protein pair to the list of protein pairs to analyze.

def mono_pred_analysis_structure_analysis_back_5(self) -> None:
6046    def mono_pred_analysis_structure_analysis_back_5(self) -> None:
6047        """Hides the gui elements to select the chains in protein 2."""
6048        gui_elements_to_show = [
6049            self._view.ui.lbl_pred_analysis_mono_overview,
6050            self._view.ui.list_pred_analysis_mono_overview,
6051            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6052            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6053            self._view.ui.lbl_analysis_batch_vs_2,
6054            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6055            self._view.ui.list_pred_analysis_mono_ref_chains,
6056            self._view.ui.btn_pred_analysis_mono_back_4,
6057            self._view.ui.btn_pred_analysis_mono_next_3,
6058        ]
6059        gui_elements_to_hide = [
6060            self._view.ui.btn_pred_analysis_mono_remove,
6061            self._view.ui.btn_pred_analysis_mono_add,
6062            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6063            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6064            self._view.ui.btn_pred_analysis_mono_back_3,
6065            self._view.ui.btn_pred_analysis_mono_next_2,
6066            self._view.ui.btn_pred_analysis_mono_back_5,
6067            self._view.ui.btn_pred_analysis_mono_next_4,
6068            self._view.ui.lbl_pred_analysis_mono_images,
6069            self._view.ui.cb_pred_analysis_mono_images,
6070            self._view.ui.btn_pred_analysis_mono_start,
6071            self._view.ui.lbl_pred_analysis_mono_model_chains,
6072            self._view.ui.list_pred_analysis_mono_model_chains,
6073            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6074        ]
6075        gui_utils.show_gui_elements(gui_elements_to_show)
6076        gui_utils.hide_gui_elements(gui_elements_to_hide)
6077        self._view.ui.list_pred_analysis_mono_ref_chains.setEnabled(True)
6078
6079        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_mono_prot_struct_2.currentText())
6080        # for tmp_chain in tmp_protein.chains:
6081        #     if tmp_chain.chain_type == "protein_chain":
6082        #         self._view.ui.list_pred_analysis_mono_ref_chains.addItem(tmp_chain.chain_letter)

Hides the gui elements to select the chains in protein 2.

def mono_pred_analysis_structure_analysis_overview_clicked(self) -> None:
6084    def mono_pred_analysis_structure_analysis_overview_clicked(self) -> None:
6085        """Enables the remove button."""
6086        self._view.ui.btn_pred_analysis_mono_remove.setEnabled(True)

Enables the remove button.

def fill_mono_pred_analysis_protein_boxes(self) -> None:
6088    def fill_mono_pred_analysis_protein_boxes(self) -> None:
6089        """Fills the combo box of the protein structures."""
6090        protein_names = []
6091        for i in range(self._view.ui.table_pred_analysis_mono_prot_to_predict.rowCount()):
6092            protein_names.append(self._view.ui.table_pred_analysis_mono_prot_to_predict.verticalHeaderItem(i).text())
6093        for tmp_protein in self._current_project.proteins:
6094            protein_names.append(tmp_protein.get_molecule_object())
6095        protein_names.insert(0, "")
6096        self._view.ui.box_pred_analysis_mono_prot_struct_1.clear()
6097        self._view.ui.box_pred_analysis_mono_prot_struct_2.clear()
6098        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_1, protein_names)
6099        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_mono_prot_struct_2, protein_names)

Fills the combo box of the protein structures.

def remove_mono_pred_analysis_analysis_run(self) -> None:
6101    def remove_mono_pred_analysis_analysis_run(self) -> None:
6102        """Removes a selected protein pair form the list of protein pairs to analyze."""
6103        self._view.ui.list_pred_analysis_mono_overview.takeItem(
6104            self._view.ui.list_pred_analysis_mono_overview.currentRow(),
6105        )
6106        gui_elements_to_show = [
6107            self._view.ui.lbl_pred_analysis_mono_overview,
6108            self._view.ui.list_pred_analysis_mono_overview,
6109            self._view.ui.btn_pred_analysis_mono_add,
6110            self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6111        ]
6112        gui_elements_to_hide = [
6113            self._view.ui.btn_pred_analysis_mono_remove,
6114            self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6115            self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6116            self._view.ui.lbl_analysis_batch_vs_2,
6117            self._view.ui.lbl_pred_analysis_mono_ref_chains,
6118            self._view.ui.list_pred_analysis_mono_ref_chains,
6119            self._view.ui.btn_pred_analysis_mono_back_4,
6120            self._view.ui.btn_pred_analysis_mono_next_3,
6121            self._view.ui.box_pred_analysis_mono_prot_struct_1,
6122            self._view.ui.box_pred_analysis_mono_prot_struct_2,
6123            self._view.ui.btn_pred_analysis_mono_back_3,
6124            self._view.ui.btn_pred_analysis_mono_next_2,
6125            self._view.ui.lbl_pred_analysis_mono_model_chains,
6126            self._view.ui.list_pred_analysis_mono_model_chains,
6127            self._view.ui.btn_pred_analysis_mono_back_5,
6128            self._view.ui.btn_pred_analysis_mono_next_4,
6129            self._view.ui.lbl_pred_analysis_mono_images,
6130            self._view.ui.cb_pred_analysis_mono_images,
6131            self._view.ui.btn_pred_analysis_mono_start,
6132        ]
6133        gui_utils.show_gui_elements(gui_elements_to_show)
6134        gui_utils.hide_gui_elements(gui_elements_to_hide)
6135        if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6136            self._view.ui.btn_pred_analysis_mono_remove.show()
6137            self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6138            self._view.ui.btn_pred_analysis_mono_start.show()
6139            self._view.ui.lbl_pred_analysis_mono_images.show()
6140            self._view.ui.cb_pred_analysis_mono_images.show()
6141        # if self._view.ui.list_pred_analysis_mono_overview.count() == 0:
6142        #
6143        #     self._view.ui.btn_pred_analysis_mono_back_pred_setup.show()
6144        #     self._view.ui.btn_pred_analysis_mono_remove.hide()

Removes a selected protein pair form the list of protein pairs to analyze.

def check_mono_pred_analysis_if_same_no_of_chains_selected(self) -> None:
6146    def check_mono_pred_analysis_if_same_no_of_chains_selected(self) -> None:
6147        """Checks if the same number of chains were selected."""
6148        self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6149        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_mono_model_chains.selectedItems()):
6150            self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(True)
6151
6152        prot_1_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_1.text()
6153        prot_1_chains = []
6154        for chain in self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems():
6155            prot_1_chains.append(chain.text())
6156        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
6157        prot_2_name = self._view.ui.lbl_pred_analysis_mono_prot_struct_2.text()
6158        prot_2_chains = []
6159        for chain in self._view.ui.list_pred_analysis_mono_model_chains.selectedItems():
6160            prot_2_chains.append(chain.text())
6161        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
6162        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
6163        for tmp_row in range(self._view.ui.list_pred_analysis_mono_overview.count()):
6164            if analysis_name == self._view.ui.list_pred_analysis_mono_overview.item(tmp_row).text():
6165                self._view.ui.btn_pred_analysis_mono_next_4.setEnabled(False)
6166                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_mono_next_4)
6167                return

Checks if the same number of chains were selected.

def check_mono_pred_analysis_if_prot_structs_are_filled(self) -> None:
6169    def check_mono_pred_analysis_if_prot_structs_are_filled(self) -> None:
6170        """Checks if two proteins were selected."""
6171        prot_1 = self._view.ui.box_pred_analysis_mono_prot_struct_1.itemText(
6172            self._view.ui.box_pred_analysis_mono_prot_struct_1.currentIndex(),
6173        )
6174        prot_2 = self._view.ui.box_pred_analysis_mono_prot_struct_2.itemText(
6175            self._view.ui.box_pred_analysis_mono_prot_struct_2.currentIndex(),
6176        )
6177        if prot_1 != "" and prot_2 != "":
6178            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(True)
6179        else:
6180            self._view.ui.btn_pred_analysis_mono_next_2.setEnabled(False)

Checks if two proteins were selected.

def count_mono_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
6182    def count_mono_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
6183        """Counts the number of chains selected in protein 1."""
6184        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_mono_ref_chains.selectedItems())
6185        if self.no_of_selected_chains > 0:
6186            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(True)
6187        else:
6188            self._view.ui.btn_pred_analysis_mono_next_3.setEnabled(False)

Counts the number of chains selected in protein 1.

def switch_monomer_pred_analysis_tab(self) -> None:
6194    def switch_monomer_pred_analysis_tab(self) -> None:
6195        """Switches the tabs from prediction to analysis and vice versa."""
6196        if self._view.ui.tabWidget.currentIndex() == 0:
6197            # goes from prediction to analysis
6198            self._view.ui.tabWidget.setTabEnabled(1, True)
6199            self._view.ui.tabWidget.setTabEnabled(0, False)
6200            self._view.ui.tabWidget.setCurrentIndex(1)
6201            gui_elements_to_show = [
6202                self._view.ui.lbl_pred_analysis_mono_overview,
6203                self._view.ui.list_pred_analysis_mono_overview,
6204                self._view.ui.btn_pred_analysis_mono_add,
6205                self._view.ui.btn_pred_analysis_mono_back_pred_setup,
6206            ]
6207            gui_elements_to_hide = [
6208                self._view.ui.btn_pred_analysis_mono_remove,
6209                self._view.ui.lbl_pred_analysis_mono_prot_struct_1,
6210                self._view.ui.lbl_pred_analysis_mono_prot_struct_2,
6211                self._view.ui.lbl_analysis_batch_vs_2,
6212                self._view.ui.lbl_pred_analysis_mono_ref_chains,
6213                self._view.ui.list_pred_analysis_mono_ref_chains,
6214                self._view.ui.btn_pred_analysis_mono_back_4,
6215                self._view.ui.btn_pred_analysis_mono_next_3,
6216                self._view.ui.box_pred_analysis_mono_prot_struct_1,
6217                self._view.ui.box_pred_analysis_mono_prot_struct_2,
6218                self._view.ui.btn_pred_analysis_mono_back_3,
6219                self._view.ui.btn_pred_analysis_mono_next_2,
6220                self._view.ui.lbl_pred_analysis_mono_model_chains,
6221                self._view.ui.list_pred_analysis_mono_model_chains,
6222                self._view.ui.btn_pred_analysis_mono_back_5,
6223                self._view.ui.btn_pred_analysis_mono_next_4,
6224                self._view.ui.lbl_pred_analysis_mono_images,
6225                self._view.ui.cb_pred_analysis_mono_images,
6226                self._view.ui.btn_pred_analysis_mono_start,
6227            ]
6228            gui_utils.show_gui_elements(gui_elements_to_show)
6229            gui_utils.hide_gui_elements(gui_elements_to_hide)
6230            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6231                self._view.ui.btn_pred_analysis_mono_remove.show()
6232                self._view.ui.btn_pred_analysis_mono_remove.setEnabled(False)
6233                self._view.ui.btn_pred_analysis_mono_start.show()
6234                self._view.ui.lbl_pred_analysis_mono_images.show()
6235                self._view.ui.cb_pred_analysis_mono_images.show()
6236        else:
6237            # goes from analysis to prediction
6238            if self._view.ui.list_pred_analysis_mono_overview.count() > 0:
6239                gui_elements_to_show = [
6240                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6241                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6242                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6243                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6244                ]
6245                gui_elements_to_hide = [
6246                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6247                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6248                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6249                    self._view.ui.txt_pred_analysis_mono_prot_name,
6250                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6251                    self._view.ui.btn_pred_analysis_mono_back,
6252                    self._view.ui.btn_pred_analysis_mono_next,
6253                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6254                    self._view.ui.txt_pred_analysis_mono_seq_name,
6255                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6256                    self._view.ui.btn_pred_analysis_mono_back_2,
6257                    self._view.ui.btn_pred_analysis_mono_add_protein,
6258                    self._view.ui.lbl_pred_mono_advanced_config_2,
6259                    self._view.ui.btn_pred_mono_advanced_config_2,
6260                ]
6261                gui_utils.show_gui_elements(gui_elements_to_show)
6262                gui_utils.hide_gui_elements(gui_elements_to_hide)
6263            else:
6264                gui_elements_to_show = [
6265                    self._view.ui.lbl_pred_analysis_mono_prot_to_predict,
6266                    self._view.ui.table_pred_analysis_mono_prot_to_predict,
6267                    self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove,
6268                    self._view.ui.btn_pred_analysis_mono_seq_to_predict,
6269                    self._view.ui.lbl_pred_mono_advanced_config_2,
6270                    self._view.ui.btn_pred_mono_advanced_config_2,
6271                    self._view.ui.btn_pred_analysis_mono_go_analysis_setup,
6272                    self._view.ui.lbl_pred_analysis_mono_to_analysis_setup,
6273                ]
6274                gui_elements_to_hide = [
6275                    self._view.ui.lbl_pred_analysis_mono_prot_name,
6276                    self._view.ui.txt_pred_analysis_mono_prot_name,
6277                    self._view.ui.lbl_pred_analysis_mono_prot_name_status,
6278                    self._view.ui.btn_pred_analysis_mono_back,
6279                    self._view.ui.btn_pred_analysis_mono_next,
6280                    self._view.ui.lbl_pred_analysis_mono_seq_name,
6281                    self._view.ui.txt_pred_analysis_mono_seq_name,
6282                    self._view.ui.lbl_pred_analysis_mono_seq_name_status,
6283                    self._view.ui.btn_pred_analysis_mono_back_2,
6284                    self._view.ui.btn_pred_analysis_mono_add_protein,
6285                ]
6286                gui_utils.show_gui_elements(gui_elements_to_show)
6287                gui_utils.hide_gui_elements(gui_elements_to_hide)
6288                self._view.ui.btn_pred_analysis_mono_seq_to_predict_remove.setEnabled(False)
6289            self._view.ui.tabWidget.setTabEnabled(0, True)
6290            self._view.ui.tabWidget.setTabEnabled(1, False)
6291            self._view.ui.tabWidget.setCurrentIndex(0)

Switches the tabs from prediction to analysis and vice versa.

def display_multimer_pred_analysis(self) -> None:
6322    def display_multimer_pred_analysis(self) -> None:
6323        """Displays the multimer prediction + analysis page."""
6324        # checks internet connection
6325        if not tools.check_internet_connectivity():
6326            gui_utils.no_internet_dialog()
6327            return
6328
6329        self._init_multi_pred_analysis_page()
6330        self._view.ui.table_pred_analysis_multi_prot_to_predict.clear()
6331        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6332            0,
6333            QtWidgets.QTableWidgetItem("Chain"),
6334        )
6335        self._view.ui.table_pred_analysis_multi_prot_to_predict.setHorizontalHeaderItem(
6336            1,
6337            QtWidgets.QTableWidgetItem("Sequence"),
6338        )
6339        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6340        gui_elements_to_show = [
6341            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6342            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6343            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6344        ]
6345        gui_elements_to_hide = [
6346            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6347            self._view.ui.lbl_pred_analysis_multi_prot_name,
6348            self._view.ui.txt_pred_analysis_multi_prot_name,
6349            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6350            self._view.ui.btn_pred_analysis_multi_back,
6351            self._view.ui.btn_pred_analysis_multi_next,
6352            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6353            self._view.ui.txt_pred_analysis_multi_prot_seq,
6354            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6355            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6356            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6357            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6358            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6359            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6360            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6361            self._view.ui.btn_pred_analysis_multi_back_2,
6362            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6363            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6364            self._view.ui.btn_pred_analysis_multi_advanced_config,
6365            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6366            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6367        ]
6368        gui_utils.show_gui_elements(gui_elements_to_show)
6369        gui_utils.hide_gui_elements(gui_elements_to_hide)
6370        if self._view.ui.tabWidget_2.currentIndex() == 1:
6371            self._view.ui.tabWidget_2.setCurrentIndex(0)
6372        self._view.ui.tabWidget_2.setTabEnabled(1, False)
6373        self._view.ui.tabWidget_2.setTabEnabled(0, True)
6374        tools.switch_page(
6375            self._view.ui.stackedWidget,
6376            self._view.ui.lbl_page_title,
6377            22,
6378            "Multimer Prediction + Analysis",
6379        )
6380        self.last_sidebar_button = styles.color_sidebar_buttons(
6381            self.last_sidebar_button,
6382            self._view.ui.btn_pred_analysis_multimer_page,
6383        )
6384        self._view.ui.table_pred_analysis_multi_prot_to_predict.setEnabled(True)

Displays the multimer prediction + analysis page.

def multi_pred_analysis_validate_protein_name(self) -> None:
6387    def multi_pred_analysis_validate_protein_name(self) -> None:
6388        """Validates the input of the protein name in real-time."""
6389        if safeguard.Safeguard.check_if_value_is_in_table_v_header(
6390            self._view.ui.txt_pred_analysis_multi_prot_name.text(),
6391            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6392        ):
6393            self._view.ui.lbl_pred_analysis_multi_prot_name_status.setText("Protein name already used.")
6394            self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6395            styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6396        else:
6397            self._view.ui.btn_pred_analysis_multi_next.setEnabled(True)
6398            tools.validate_protein_name(
6399                self._view.ui.txt_pred_analysis_multi_prot_name,
6400                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6401                self._view.ui.btn_pred_analysis_multi_next,
6402            )

Validates the input of the protein name in real-time.

def multi_pred_analysis_validate_protein_sequence(self) -> None:
6404    def multi_pred_analysis_validate_protein_sequence(self) -> None:
6405        """Validates the input of the protein sequence in real-time."""
6406        tools.validate_protein_sequence(
6407            self._view.ui.txt_pred_analysis_multi_prot_seq,
6408            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6409            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6410        )

Validates the input of the protein sequence in real-time.

def multi_pred_analysis_check_if_list_is_empty(self) -> None:
6412    def multi_pred_analysis_check_if_list_is_empty(self) -> None:
6413        """Checks if the list of sequences of the protein is empty."""
6414        if self._view.ui.list_pred_analysis_multi_prot_seq_overview.count() == 0:
6415            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6416        else:
6417            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(True)

Checks if the list of sequences of the protein is empty.

def multi_pred_analysis_add_sequence_to_list(self) -> None:
6419    def multi_pred_analysis_add_sequence_to_list(self) -> None:
6420        """Adds the entered sequence to the sequences of the protein."""
6421        self._view.ui.list_pred_analysis_multi_prot_seq_overview.addItem(
6422            QtWidgets.QListWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_seq.toPlainText()),
6423        )
6424        self.multi_pred_analysis_check_if_list_is_empty()

Adds the entered sequence to the sequences of the protein.

def multi_pred_analysis_remove_sequence_to_list(self) -> None:
6426    def multi_pred_analysis_remove_sequence_to_list(self) -> None:
6427        """Removes the entered sequence from the sequences of the protein."""
6428        self._view.ui.list_pred_analysis_multi_prot_seq_overview.takeItem(
6429            self._view.ui.list_pred_analysis_multi_prot_seq_overview.currentRow(),
6430        )
6431        self.multi_pred_analysis_check_if_list_is_empty()
6432        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)

Removes the entered sequence from the sequences of the protein.

def multi_pred_analysis_check_if_table_is_empty(self) -> None:
6434    def multi_pred_analysis_check_if_table_is_empty(self) -> None:
6435        """Checks if the list of proteins to predict is empty."""
6436        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 0:
6437            styles.color_button_not_ready(self._view.ui.btn_pred_multi_predict)
6438            gui_elements_to_show = [
6439                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6440                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6441                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6442            ]
6443            gui_elements_to_hide = [
6444                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6445                self._view.ui.lbl_pred_analysis_multi_prot_name,
6446                self._view.ui.txt_pred_analysis_multi_prot_name,
6447                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6448                self._view.ui.btn_pred_analysis_multi_back,
6449                self._view.ui.btn_pred_analysis_multi_next,
6450                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6451                self._view.ui.txt_pred_analysis_multi_prot_seq,
6452                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6453                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6454                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6455                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6456                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6457                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6458                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6459                self._view.ui.btn_pred_analysis_multi_back_2,
6460                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6461                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6462                self._view.ui.btn_pred_analysis_multi_advanced_config,
6463                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6464                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6465            ]
6466            gui_utils.show_gui_elements(gui_elements_to_show)
6467            gui_utils.hide_gui_elements(gui_elements_to_hide)
6468            self._view.ui.btn_pred_multi_predict.setEnabled(False)
6469            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)
6470        else:
6471            self._view.ui.btn_pred_multi_predict.setEnabled(True)
6472            gui_elements_to_show = [
6473                self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6474                self._view.ui.table_pred_analysis_multi_prot_to_predict,
6475                self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6476                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6477                self._view.ui.lbl_pred_analysis_multi_advanced_config,
6478                self._view.ui.btn_pred_analysis_multi_advanced_config,
6479                self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6480                self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6481            ]
6482            gui_elements_to_hide = [
6483                self._view.ui.lbl_pred_analysis_multi_prot_name,
6484                self._view.ui.txt_pred_analysis_multi_prot_name,
6485                self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6486                self._view.ui.btn_pred_analysis_multi_back,
6487                self._view.ui.btn_pred_analysis_multi_next,
6488                self._view.ui.lbl_pred_analysis_multi_prot_seq,
6489                self._view.ui.txt_pred_analysis_multi_prot_seq,
6490                self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6491                self._view.ui.lbl_pred_multi_prot_seq_add_2,
6492                self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6493                self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6494                self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6495                self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6496                self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6497                self._view.ui.btn_pred_analysis_multi_back_2,
6498                self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6499            ]
6500            gui_utils.show_gui_elements(gui_elements_to_show)
6501            gui_utils.hide_gui_elements(gui_elements_to_hide)
6502            self._view.ui.btn_pred_multi_prot_to_predict_remove.setEnabled(False)

Checks if the list of proteins to predict is empty.

def multi_pred_analysis_add_protein_to_predict(self) -> None:
6504    def multi_pred_analysis_add_protein_to_predict(self) -> None:
6505        """Adds the proteins to the list of proteins to predict."""
6506        for i in range(self._view.ui.list_pred_analysis_multi_prot_seq_overview.count()):
6507            self._view.ui.table_pred_analysis_multi_prot_to_predict.setRowCount(
6508                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6509            )
6510            self._view.ui.table_pred_analysis_multi_prot_to_predict.insertRow(
6511                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() + 1,
6512            )
6513            tmp_chain_seq = (
6514                constants.chain_dict.get(i),
6515                self._view.ui.list_pred_analysis_multi_prot_seq_overview.item(i).text(),
6516            )
6517            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6518                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6519                0,
6520                QtWidgets.QTableWidgetItem(tmp_chain_seq[0]),
6521            )
6522            self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6523                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6524                1,
6525                QtWidgets.QTableWidgetItem(tmp_chain_seq[1]),
6526            )
6527            name_item = QtWidgets.QTableWidgetItem(self._view.ui.txt_pred_analysis_multi_prot_name.text())
6528            self._view.ui.table_pred_analysis_multi_prot_to_predict.setVerticalHeaderItem(
6529                self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() - 1,
6530                name_item,
6531            )
6532        self._view.ui.table_pred_analysis_multi_prot_to_predict.resizeColumnsToContents()
6533        self.multi_pred_analysis_check_if_table_is_empty()
6534        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)

Adds the proteins to the list of proteins to predict.

def multi_pred_analysis_remove_protein_to_predict(self) -> None:
6536    def multi_pred_analysis_remove_protein_to_predict(self) -> None:
6537        """Removes the selected protein from the list of proteins to predict."""
6538        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() == 1:
6539            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(0)
6540        else:
6541            self._view.ui.table_pred_analysis_multi_prot_to_predict.removeRow(
6542                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6543            )
6544            prot_name = self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(
6545                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentRow(),
6546            ).text()
6547            for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6548                if self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text() == prot_name:
6549                    self._view.ui.table_pred_analysis_multi_prot_to_predict.setItem(
6550                        i,
6551                        0,
6552                        QtWidgets.QTableWidgetItem(constants.chain_dict.get(i)),
6553                    )
6554        self.multi_pred_analysis_check_if_table_is_empty()
6555        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(False)

Removes the selected protein from the list of proteins to predict.

def multi_pred_analysis_add(self) -> None:
6557    def multi_pred_analysis_add(self) -> None:
6558        """Shows the gui elements for the protein name."""
6559        gui_elements_to_show = [
6560            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6561            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6562            self._view.ui.lbl_pred_analysis_multi_prot_name,
6563            self._view.ui.txt_pred_analysis_multi_prot_name,
6564            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6565            self._view.ui.btn_pred_analysis_multi_back,
6566            self._view.ui.btn_pred_analysis_multi_next,
6567        ]
6568        gui_elements_to_hide = [
6569            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6570            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6571            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6572            self._view.ui.txt_pred_analysis_multi_prot_seq,
6573            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6574            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6575            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6576            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6577            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6578            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6579            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6580            self._view.ui.btn_pred_analysis_multi_back_2,
6581            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6582            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6583            self._view.ui.btn_pred_analysis_multi_advanced_config,
6584            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6585            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6586        ]
6587        gui_utils.show_gui_elements(gui_elements_to_show)
6588        gui_utils.hide_gui_elements(gui_elements_to_hide)
6589        gui_utils.enable_text_box(
6590            self._view.ui.txt_pred_analysis_multi_prot_name,
6591            self._view.ui.lbl_pred_analysis_multi_prot_name,
6592        )
6593        gui_utils.disable_text_box(
6594            self._view.ui.txt_pred_analysis_multi_prot_seq,
6595            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6596        )
6597        self._view.ui.btn_pred_analysis_multi_next.setEnabled(False)
6598        self._view.ui.txt_pred_analysis_multi_prot_name.clear()
6599        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next)
6600        if self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount() > 0:
6601            try:
6602                self._view.ui.table_pred_analysis_multi_prot_to_predict.currentItem().setSelected(False)
6603            except AttributeError:
6604                constants.PYSSA_LOGGER.debug("No selection on Local Multimer Prediction in overview table.")

Shows the gui elements for the protein name.

def multi_pred_analysis_back(self) -> None:
6606    def multi_pred_analysis_back(self) -> None:
6607        """Hides the gui elements for the protein name."""
6608        gui_elements_to_show = [
6609            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6610            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6611            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6612        ]
6613        gui_elements_to_hide = [
6614            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6615            self._view.ui.lbl_pred_analysis_multi_prot_name,
6616            self._view.ui.txt_pred_analysis_multi_prot_name,
6617            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6618            self._view.ui.btn_pred_analysis_multi_back,
6619            self._view.ui.btn_pred_analysis_multi_next,
6620            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6621            self._view.ui.txt_pred_analysis_multi_prot_seq,
6622            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6623            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6624            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6625            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6626            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6627            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6628            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6629            self._view.ui.btn_pred_analysis_multi_back_2,
6630            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6631            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6632            self._view.ui.btn_pred_analysis_multi_advanced_config,
6633            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6634            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6635        ]
6636        gui_utils.show_gui_elements(gui_elements_to_show)
6637        gui_utils.hide_gui_elements(gui_elements_to_hide)
6638        self.multi_pred_analysis_check_if_table_is_empty()

Hides the gui elements for the protein name.

def multi_pred_analysis_next(self) -> None:
6640    def multi_pred_analysis_next(self) -> None:
6641        """Shows the gui elements for the protein sequence."""
6642        gui_elements_to_show = [
6643            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6644            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6645            self._view.ui.lbl_pred_analysis_multi_prot_name,
6646            self._view.ui.txt_pred_analysis_multi_prot_name,
6647            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6648            self._view.ui.txt_pred_analysis_multi_prot_seq,
6649            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6650            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6651            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6652            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6653            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6654            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6655            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6656            self._view.ui.btn_pred_analysis_multi_back_2,
6657            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6658        ]
6659        gui_elements_to_hide = [
6660            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6661            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6662            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6663            self._view.ui.btn_pred_analysis_multi_back,
6664            self._view.ui.btn_pred_analysis_multi_next,
6665            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6666            self._view.ui.btn_pred_analysis_multi_advanced_config,
6667            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6668            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6669        ]
6670        gui_utils.show_gui_elements(gui_elements_to_show)
6671        gui_utils.hide_gui_elements(gui_elements_to_hide)
6672        gui_utils.enable_text_box(
6673            self._view.ui.txt_pred_analysis_multi_prot_seq,
6674            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6675        )
6676        gui_utils.disable_text_box(
6677            self._view.ui.txt_pred_analysis_multi_prot_name,
6678            self._view.ui.lbl_pred_analysis_multi_prot_name,
6679        )
6680        self._view.ui.txt_pred_analysis_multi_prot_seq.clear()
6681        self._view.ui.list_pred_analysis_multi_prot_seq_overview.clear()
6682        self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2.setEnabled(False)
6683        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(False)
6684        styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2)

Shows the gui elements for the protein sequence.

def multi_pred_analysis_back_2(self) -> None:
6686    def multi_pred_analysis_back_2(self) -> None:
6687        """Hides the gui elements for the protein sequence."""
6688        gui_elements_to_show = [
6689            self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6690            self._view.ui.table_pred_analysis_multi_prot_to_predict,
6691            self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6692            self._view.ui.btn_pred_analysis_multi_back,
6693            self._view.ui.btn_pred_analysis_multi_next,
6694            self._view.ui.lbl_pred_analysis_multi_prot_name,
6695            self._view.ui.txt_pred_analysis_multi_prot_name,
6696        ]
6697        gui_elements_to_hide = [
6698            self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6699            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6700            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6701            self._view.ui.txt_pred_analysis_multi_prot_seq,
6702            self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6703            self._view.ui.lbl_pred_multi_prot_seq_add_2,
6704            self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6705            self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6706            self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6707            self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6708            self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6709            self._view.ui.btn_pred_analysis_multi_back_2,
6710            self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6711            self._view.ui.lbl_pred_analysis_multi_advanced_config,
6712            self._view.ui.btn_pred_analysis_multi_advanced_config,
6713            self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6714            self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6715        ]
6716        gui_utils.show_gui_elements(gui_elements_to_show)
6717        gui_utils.hide_gui_elements(gui_elements_to_hide)
6718        gui_utils.enable_text_box(
6719            self._view.ui.txt_pred_analysis_multi_prot_name,
6720            self._view.ui.lbl_pred_analysis_multi_prot_name,
6721        )
6722        gui_utils.disable_text_box(
6723            self._view.ui.txt_pred_analysis_multi_prot_seq,
6724            self._view.ui.lbl_pred_analysis_multi_prot_seq,
6725        )

Hides the gui elements for the protein sequence.

def multi_pred_analysis_prot_seq_overview_item_changed(self) -> None:
6727    def multi_pred_analysis_prot_seq_overview_item_changed(self) -> None:
6728        """Enables the remove button of the list of sequences of the protein."""
6729        self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove.setEnabled(True)

Enables the remove button of the list of sequences of the protein.

def multi_pred_analysis_prot_to_predict_item_changed(self) -> None:
6731    def multi_pred_analysis_prot_to_predict_item_changed(self) -> None:
6732        """Enables the remove button of the list of proteins to predict."""
6733        self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove.setEnabled(True)

Enables the remove button of the list of proteins to predict.

def switch_multimer_pred_analysis_tab(self) -> None:
6737    def switch_multimer_pred_analysis_tab(self) -> None:
6738        """Switches the tabs from prediction to analysis and vice versa."""
6739        if self._view.ui.tabWidget_2.currentIndex() == 0:
6740            # goes from prediction to analysis
6741            self._view.ui.tabWidget_2.setCurrentIndex(1)
6742            gui_elements_to_show = [
6743                self._view.ui.lbl_pred_analysis_multi_overview,
6744                self._view.ui.list_pred_analysis_multi_overview,
6745                self._view.ui.btn_pred_analysis_multi_add,
6746                self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6747            ]
6748            gui_elements_to_hide = [
6749                self._view.ui.btn_pred_analysis_multi_remove,
6750                self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6751                self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6752                self._view.ui.lbl_analysis_batch_vs_3,
6753                self._view.ui.lbl_pred_analysis_multi_ref_chains,
6754                self._view.ui.list_pred_analysis_multi_ref_chains,
6755                self._view.ui.btn_pred_analysis_multi_back_4,
6756                self._view.ui.btn_pred_analysis_multi_next_3,
6757                self._view.ui.box_pred_analysis_multi_prot_struct_1,
6758                self._view.ui.box_pred_analysis_multi_prot_struct_2,
6759                self._view.ui.btn_pred_analysis_multi_back_3,
6760                self._view.ui.btn_pred_analysis_multi_next_2,
6761                self._view.ui.lbl_pred_analysis_multi_model_chains,
6762                self._view.ui.list_pred_analysis_multi_model_chains,
6763                self._view.ui.btn_pred_analysis_multi_back_5,
6764                self._view.ui.btn_pred_analysis_multi_next_4,
6765                self._view.ui.lbl_pred_analysis_multi_images,
6766                self._view.ui.cb_pred_analysis_multi_images,
6767                self._view.ui.btn_pred_analysis_multi_start,
6768            ]
6769            gui_utils.show_gui_elements(gui_elements_to_show)
6770            gui_utils.hide_gui_elements(gui_elements_to_hide)
6771            self._view.ui.tabWidget_2.setTabEnabled(1, True)
6772            self._view.ui.tabWidget_2.setTabEnabled(0, False)
6773            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6774                self._view.ui.btn_pred_analysis_multi_remove.show()
6775                self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6776                self._view.ui.btn_pred_analysis_multi_start.show()
6777                self._view.ui.lbl_pred_analysis_multi_images.show()
6778                self._view.ui.cb_pred_analysis_multi_images.show()
6779        else:
6780            # goes from analysis to prediction
6781            self._view.ui.tabWidget_2.setCurrentIndex(0)
6782            if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6783                gui_elements_to_show = [
6784                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6785                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6786                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6787                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6788                ]
6789                gui_elements_to_hide = [
6790                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6791                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6792                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6793                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6794                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6795                    self._view.ui.txt_pred_analysis_multi_prot_name,
6796                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6797                    self._view.ui.btn_pred_analysis_multi_back,
6798                    self._view.ui.btn_pred_analysis_multi_next,
6799                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6800                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6801                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6802                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6803                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6804                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6805                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6806                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6807                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6808                    self._view.ui.btn_pred_analysis_multi_back_2,
6809                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6810                ]
6811                gui_utils.show_gui_elements(gui_elements_to_show)
6812                gui_utils.hide_gui_elements(gui_elements_to_hide)
6813            else:
6814                gui_elements_to_show = [
6815                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict,
6816                    self._view.ui.table_pred_analysis_multi_prot_to_predict,
6817                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_remove,
6818                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add,
6819                    self._view.ui.lbl_pred_analysis_multi_advanced_config,
6820                    self._view.ui.btn_pred_analysis_multi_advanced_config,
6821                    self._view.ui.btn_pred_analysis_multi_go_analysis_setup,
6822                    self._view.ui.lbl_pred_analysis_multi_to_analysis_setup,
6823                ]
6824                gui_elements_to_hide = [
6825                    self._view.ui.lbl_pred_analysis_multi_prot_name,
6826                    self._view.ui.txt_pred_analysis_multi_prot_name,
6827                    self._view.ui.lbl_pred_analysis_multi_prot_name_status,
6828                    self._view.ui.btn_pred_analysis_multi_back,
6829                    self._view.ui.btn_pred_analysis_multi_next,
6830                    self._view.ui.lbl_pred_analysis_multi_prot_seq,
6831                    self._view.ui.txt_pred_analysis_multi_prot_seq,
6832                    self._view.ui.lbl_pred_analysis_multi_prot_seq_status,
6833                    self._view.ui.lbl_pred_multi_prot_seq_add_2,
6834                    self._view.ui.btn_pred_analysis_multi_prot_seq_add,
6835                    self._view.ui.lbl_pred_analysis_multi_prot_seq_overview,
6836                    self._view.ui.list_pred_analysis_multi_prot_seq_overview,
6837                    self._view.ui.btn_pred_analysis_multi_prot_seq_overview_remove,
6838                    self._view.ui.lbl_pred_analysis_multi_prot_to_predict_2,
6839                    self._view.ui.btn_pred_analysis_multi_back_2,
6840                    self._view.ui.btn_pred_analysis_multi_prot_to_predict_add_2,
6841                ]
6842                gui_utils.show_gui_elements(gui_elements_to_show)
6843                gui_utils.hide_gui_elements(gui_elements_to_hide)
6844            self._view.ui.tabWidget_2.setTabEnabled(0, True)
6845            self._view.ui.tabWidget_2.setTabEnabled(1, False)

Switches the tabs from prediction to analysis and vice versa.

def multi_pred_analysis_structure_analysis_add(self) -> None:
6848    def multi_pred_analysis_structure_analysis_add(self) -> None:
6849        """Shows the gui elements to choose the two proteins."""
6850        gui_elements_to_show = [
6851            self._view.ui.lbl_pred_analysis_multi_overview,
6852            self._view.ui.list_pred_analysis_multi_overview,
6853            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6854            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6855            self._view.ui.lbl_analysis_batch_vs_3,
6856            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6857            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6858            self._view.ui.btn_pred_analysis_multi_back_3,
6859            self._view.ui.btn_pred_analysis_multi_next_2,
6860        ]
6861        gui_elements_to_hide = [
6862            self._view.ui.btn_pred_analysis_multi_remove,
6863            self._view.ui.btn_pred_analysis_multi_add,
6864            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6865            self._view.ui.list_pred_analysis_multi_ref_chains,
6866            self._view.ui.btn_pred_analysis_multi_back_4,
6867            self._view.ui.btn_pred_analysis_multi_next_3,
6868            self._view.ui.lbl_pred_analysis_multi_model_chains,
6869            self._view.ui.list_pred_analysis_multi_model_chains,
6870            self._view.ui.btn_pred_analysis_multi_back_5,
6871            self._view.ui.btn_pred_analysis_multi_next_4,
6872            self._view.ui.lbl_pred_analysis_multi_images,
6873            self._view.ui.cb_pred_analysis_multi_images,
6874            self._view.ui.btn_pred_analysis_multi_start,
6875            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6876        ]
6877        gui_utils.show_gui_elements(gui_elements_to_show)
6878        gui_utils.hide_gui_elements(gui_elements_to_hide)
6879        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.clear()
6880        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.clear()
6881        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
6882        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")
6883        self.fill_multi_pred_analysis_protein_boxes()
6884        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6885            try:
6886                self._view.ui.list_pred_analysis_multi_overview.currentItem().setSelected(False)
6887            except AttributeError:
6888                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")

Shows the gui elements to choose the two proteins.

def multi_pred_analysis_structure_analysis_back_3(self) -> None:
6890    def multi_pred_analysis_structure_analysis_back_3(self) -> None:
6891        """Hides the gui elements to choose the two proteins."""
6892        gui_elements_to_show = [
6893            self._view.ui.lbl_pred_analysis_multi_overview,
6894            self._view.ui.list_pred_analysis_multi_overview,
6895            self._view.ui.btn_pred_analysis_multi_add,
6896            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6897        ]
6898        gui_elements_to_hide = [
6899            self._view.ui.btn_pred_analysis_multi_remove,
6900            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6901            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6902            self._view.ui.lbl_analysis_batch_vs_3,
6903            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6904            self._view.ui.list_pred_analysis_multi_ref_chains,
6905            self._view.ui.btn_pred_analysis_multi_back_4,
6906            self._view.ui.btn_pred_analysis_multi_next_3,
6907            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6908            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6909            self._view.ui.btn_pred_analysis_multi_back_3,
6910            self._view.ui.btn_pred_analysis_multi_next_2,
6911            self._view.ui.lbl_pred_analysis_multi_model_chains,
6912            self._view.ui.list_pred_analysis_multi_model_chains,
6913            self._view.ui.btn_pred_analysis_multi_back_5,
6914            self._view.ui.btn_pred_analysis_multi_next_4,
6915            self._view.ui.lbl_pred_analysis_multi_images,
6916            self._view.ui.cb_pred_analysis_multi_images,
6917            self._view.ui.btn_pred_analysis_multi_start,
6918        ]
6919        gui_utils.show_gui_elements(gui_elements_to_show)
6920        gui_utils.hide_gui_elements(gui_elements_to_hide)
6921        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
6922            self._view.ui.btn_pred_analysis_multi_remove.show()
6923            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
6924            self._view.ui.btn_pred_analysis_multi_start.show()
6925            self._view.ui.lbl_pred_analysis_multi_images.show()
6926            self._view.ui.cb_pred_analysis_multi_images.show()

Hides the gui elements to choose the two proteins.

def multi_pred_analysis_structure_analysis_next_3(self) -> None:
6928    def multi_pred_analysis_structure_analysis_next_3(self) -> None:
6929        """Shows the gui elements to select the chains in protein 2."""
6930        gui_elements_to_show = [
6931            self._view.ui.lbl_pred_analysis_multi_overview,
6932            self._view.ui.list_pred_analysis_multi_overview,
6933            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6934            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6935            self._view.ui.lbl_analysis_batch_vs_3,
6936            self._view.ui.lbl_pred_analysis_multi_ref_chains,
6937            self._view.ui.list_pred_analysis_multi_ref_chains,
6938            self._view.ui.lbl_pred_analysis_multi_model_chains,
6939            self._view.ui.list_pred_analysis_multi_model_chains,
6940            self._view.ui.btn_pred_analysis_multi_back_5,
6941            self._view.ui.btn_pred_analysis_multi_next_4,
6942        ]
6943        gui_elements_to_hide = [
6944            self._view.ui.btn_pred_analysis_multi_remove,
6945            self._view.ui.btn_pred_analysis_multi_add,
6946            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6947            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6948            self._view.ui.btn_pred_analysis_multi_back_3,
6949            self._view.ui.btn_pred_analysis_multi_next_2,
6950            self._view.ui.btn_pred_analysis_multi_back_4,
6951            self._view.ui.btn_pred_analysis_multi_next_3,
6952            self._view.ui.lbl_pred_analysis_multi_images,
6953            self._view.ui.cb_pred_analysis_multi_images,
6954            self._view.ui.btn_pred_analysis_multi_start,
6955            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
6956        ]
6957        gui_utils.show_gui_elements(gui_elements_to_show)
6958        gui_utils.hide_gui_elements(gui_elements_to_hide)
6959        self._view.ui.list_pred_analysis_multi_model_chains.clear()
6960        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(False)
6961        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
6962
6963        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
6964            if (
6965                self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text()
6966                == self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText()
6967            ):
6968                self._view.ui.list_pred_analysis_multi_model_chains.addItem(
6969                    self._view.ui.table_pred_analysis_multi_prot_to_predict.item(i, 0).text(),
6970                )
6971        if self._view.ui.list_pred_analysis_multi_model_chains.count() == 0:
6972            tmp_protein = self._current_project.search_protein(
6973                self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText(),
6974            )
6975            for tmp_chain in tmp_protein.chains:
6976                if tmp_chain.chain_type == "protein_chain":
6977                    self._view.ui.list_pred_analysis_multi_model_chains.addItem(tmp_chain.chain_letter)
6978        if len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems()) == 1:
6979            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6980                f"Select 1 chain in protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6981            )
6982        else:
6983            self._view.ui.lbl_pred_analysis_multi_model_chains.setText(
6984                f"Select {len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())} chains in "
6985                f"protein structure {self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()}.",
6986            )

Shows the gui elements to select the chains in protein 2.

def multi_pred_analysis_structure_analysis_back_4(self) -> None:
6988    def multi_pred_analysis_structure_analysis_back_4(self) -> None:
6989        """Hides the gui elements to select the chains in protein 1."""
6990        gui_elements_to_show = [
6991            self._view.ui.lbl_pred_analysis_multi_overview,
6992            self._view.ui.list_pred_analysis_multi_overview,
6993            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
6994            self._view.ui.box_pred_analysis_multi_prot_struct_1,
6995            self._view.ui.lbl_analysis_batch_vs_3,
6996            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
6997            self._view.ui.box_pred_analysis_multi_prot_struct_2,
6998            self._view.ui.btn_pred_analysis_multi_back_3,
6999            self._view.ui.btn_pred_analysis_multi_next_2,
7000            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7001        ]
7002        gui_elements_to_hide = [
7003            self._view.ui.btn_pred_analysis_multi_remove,
7004            self._view.ui.btn_pred_analysis_multi_add,
7005            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7006            self._view.ui.list_pred_analysis_multi_ref_chains,
7007            self._view.ui.btn_pred_analysis_multi_back_4,
7008            self._view.ui.btn_pred_analysis_multi_next_3,
7009            self._view.ui.lbl_pred_analysis_multi_model_chains,
7010            self._view.ui.list_pred_analysis_multi_model_chains,
7011            self._view.ui.btn_pred_analysis_multi_back_5,
7012            self._view.ui.btn_pred_analysis_multi_next_4,
7013            self._view.ui.lbl_pred_analysis_multi_images,
7014            self._view.ui.cb_pred_analysis_multi_images,
7015            self._view.ui.btn_pred_analysis_multi_start,
7016        ]
7017        gui_utils.show_gui_elements(gui_elements_to_show)
7018        gui_utils.hide_gui_elements(gui_elements_to_hide)
7019        self._view.ui.lbl_pred_analysis_multi_prot_struct_1.setText("Protein structure 1")
7020        self._view.ui.lbl_pred_analysis_multi_prot_struct_2.setText("Protein structure 2")

Hides the gui elements to select the chains in protein 1.

def multi_pred_analysis_structure_analysis_next_4(self) -> None:
7022    def multi_pred_analysis_structure_analysis_next_4(self) -> None:
7023        """Adds the protein pair to the list of protein pairs to analyze."""
7024        gui_elements_to_show = [
7025            self._view.ui.btn_pred_analysis_multi_remove,
7026            self._view.ui.btn_pred_analysis_multi_add,
7027            self._view.ui.lbl_pred_analysis_multi_overview,
7028            self._view.ui.list_pred_analysis_multi_overview,
7029            self._view.ui.lbl_pred_analysis_multi_images,
7030            self._view.ui.cb_pred_analysis_multi_images,
7031            self._view.ui.btn_pred_analysis_multi_start,
7032            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7033        ]
7034        gui_elements_to_hide = [
7035            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7036            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7037            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7038            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7039            self._view.ui.lbl_analysis_batch_vs_3,
7040            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7041            self._view.ui.list_pred_analysis_multi_ref_chains,
7042            self._view.ui.lbl_pred_analysis_multi_model_chains,
7043            self._view.ui.list_pred_analysis_multi_model_chains,
7044            self._view.ui.btn_pred_analysis_multi_back_3,
7045            self._view.ui.btn_pred_analysis_multi_next_2,
7046            self._view.ui.btn_pred_analysis_multi_back_4,
7047            self._view.ui.btn_pred_analysis_multi_next_3,
7048            self._view.ui.btn_pred_analysis_multi_back_5,
7049            self._view.ui.btn_pred_analysis_multi_next_4,
7050        ]
7051        gui_utils.show_gui_elements(gui_elements_to_show)
7052        gui_utils.hide_gui_elements(gui_elements_to_hide)
7053        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7054        prot_1_chains = []
7055        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7056            prot_1_chains.append(chain.text())
7057        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7058        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7059        prot_2_chains = []
7060        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7061            prot_2_chains.append(chain.text())
7062        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7063        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7064        item = QtWidgets.QListWidgetItem(analysis_name)
7065        self._view.ui.list_pred_analysis_multi_overview.addItem(item)
7066        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)

Adds the protein pair to the list of protein pairs to analyze.

def multi_pred_analysis_structure_analysis_back_5(self) -> None:
7068    def multi_pred_analysis_structure_analysis_back_5(self) -> None:
7069        """Hides the gui elements to select the chains in protein 2."""
7070        gui_elements_to_show = [
7071            self._view.ui.lbl_pred_analysis_multi_overview,
7072            self._view.ui.list_pred_analysis_multi_overview,
7073            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7074            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7075            self._view.ui.lbl_analysis_batch_vs_3,
7076            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7077            self._view.ui.list_pred_analysis_multi_ref_chains,
7078            self._view.ui.btn_pred_analysis_multi_back_4,
7079            self._view.ui.btn_pred_analysis_multi_next_3,
7080        ]
7081        gui_elements_to_hide = [
7082            self._view.ui.btn_pred_analysis_multi_remove,
7083            self._view.ui.btn_pred_analysis_multi_add,
7084            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7085            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7086            self._view.ui.btn_pred_analysis_multi_back_3,
7087            self._view.ui.btn_pred_analysis_multi_next_2,
7088            self._view.ui.btn_pred_analysis_multi_back_5,
7089            self._view.ui.btn_pred_analysis_multi_next_4,
7090            self._view.ui.lbl_pred_analysis_multi_images,
7091            self._view.ui.cb_pred_analysis_multi_images,
7092            self._view.ui.btn_pred_analysis_multi_start,
7093            self._view.ui.lbl_pred_analysis_multi_model_chains,
7094            self._view.ui.list_pred_analysis_multi_model_chains,
7095            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7096        ]
7097        gui_utils.show_gui_elements(gui_elements_to_show)
7098        gui_utils.hide_gui_elements(gui_elements_to_hide)
7099        self._view.ui.list_pred_analysis_multi_ref_chains.setEnabled(True)
7100
7101        # tmp_protein = self._current_project.search_protein(self._view.ui.box_pred_analysis_multi_prot_struct_2.currentText())
7102        # for tmp_chain in tmp_protein.chains:
7103        #     if tmp_chain.chain_type == "protein_chain":
7104        #         self._view.ui.list_pred_analysis_multi_ref_chains.addItem(tmp_chain.chain_letter)

Hides the gui elements to select the chains in protein 2.

def multi_pred_analysis_structure_analysis_overview_clicked(self) -> None:
7106    def multi_pred_analysis_structure_analysis_overview_clicked(self) -> None:
7107        """Enables the remove button."""
7108        self._view.ui.btn_pred_analysis_multi_remove.setEnabled(True)

Enables the remove button.

def fill_multi_pred_analysis_protein_boxes(self) -> None:
7110    def fill_multi_pred_analysis_protein_boxes(self) -> None:
7111        """Fills the combo boxes with the protein names."""
7112        protein_names = []
7113        for i in range(self._view.ui.table_pred_analysis_multi_prot_to_predict.rowCount()):
7114            protein_names.append(self._view.ui.table_pred_analysis_multi_prot_to_predict.verticalHeaderItem(i).text())
7115        for tmp_protein in self._current_project.proteins:
7116            protein_names.append(tmp_protein.get_molecule_object())
7117        protein_names.insert(0, "")
7118        protein_names = list(set(protein_names))
7119        self._view.ui.box_pred_analysis_multi_prot_struct_1.clear()
7120        self._view.ui.box_pred_analysis_multi_prot_struct_2.clear()
7121        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_1, protein_names)
7122        gui_utils.fill_combo_box(self._view.ui.box_pred_analysis_multi_prot_struct_2, protein_names)

Fills the combo boxes with the protein names.

def remove_multi_pred_analysis_analysis_run(self) -> None:
7124    def remove_multi_pred_analysis_analysis_run(self) -> None:
7125        """Removes the selected protein pair from the list of protein pairs to analyze."""
7126        self._view.ui.list_pred_analysis_multi_overview.takeItem(
7127            self._view.ui.list_pred_analysis_multi_overview.currentRow(),
7128        )
7129        gui_elements_to_show = [
7130            self._view.ui.lbl_pred_analysis_multi_overview,
7131            self._view.ui.list_pred_analysis_multi_overview,
7132            self._view.ui.btn_pred_analysis_multi_add,
7133            self._view.ui.btn_pred_analysis_multi_back_pred_setup,
7134        ]
7135        gui_elements_to_hide = [
7136            self._view.ui.btn_pred_analysis_multi_remove,
7137            self._view.ui.lbl_pred_analysis_multi_prot_struct_1,
7138            self._view.ui.lbl_pred_analysis_multi_prot_struct_2,
7139            self._view.ui.lbl_analysis_batch_vs_3,
7140            self._view.ui.lbl_pred_analysis_multi_ref_chains,
7141            self._view.ui.list_pred_analysis_multi_ref_chains,
7142            self._view.ui.btn_pred_analysis_multi_back_4,
7143            self._view.ui.btn_pred_analysis_multi_next_3,
7144            self._view.ui.box_pred_analysis_multi_prot_struct_1,
7145            self._view.ui.box_pred_analysis_multi_prot_struct_2,
7146            self._view.ui.btn_pred_analysis_multi_back_3,
7147            self._view.ui.btn_pred_analysis_multi_next_2,
7148            self._view.ui.lbl_pred_analysis_multi_model_chains,
7149            self._view.ui.list_pred_analysis_multi_model_chains,
7150            self._view.ui.btn_pred_analysis_multi_back_5,
7151            self._view.ui.btn_pred_analysis_multi_next_4,
7152            self._view.ui.lbl_pred_analysis_multi_images,
7153            self._view.ui.cb_pred_analysis_multi_images,
7154            self._view.ui.btn_pred_analysis_multi_start,
7155        ]
7156        gui_utils.show_gui_elements(gui_elements_to_show)
7157        gui_utils.hide_gui_elements(gui_elements_to_hide)
7158        if self._view.ui.list_pred_analysis_multi_overview.count() > 0:
7159            self._view.ui.btn_pred_analysis_multi_remove.show()
7160            self._view.ui.btn_pred_analysis_multi_remove.setEnabled(False)
7161            self._view.ui.btn_pred_analysis_multi_start.show()
7162            self._view.ui.lbl_pred_analysis_multi_images.show()
7163            self._view.ui.cb_pred_analysis_multi_images.show()
7164        # if self._view.ui.list_pred_analysis_multi_overview.count() == 0:
7165        #
7166        #     self._view.ui.btn_pred_analysis_multi_back_pred_setup.show()
7167        #     self._view.ui.btn_pred_analysis_multi_remove.hide()

Removes the selected protein pair from the list of protein pairs to analyze.

def check_multi_pred_analysis_if_same_no_of_chains_selected(self) -> None:
7169    def check_multi_pred_analysis_if_same_no_of_chains_selected(self) -> None:
7170        """Checks if the same number of chains were selected."""
7171        self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7172        if self.no_of_selected_chains == len(self._view.ui.list_pred_analysis_multi_model_chains.selectedItems()):
7173            self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(True)
7174
7175        prot_1_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_1.text()
7176        prot_1_chains = []
7177        for chain in self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems():
7178            prot_1_chains.append(chain.text())
7179        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7180        prot_2_name = self._view.ui.lbl_pred_analysis_multi_prot_struct_2.text()
7181        prot_2_chains = []
7182        for chain in self._view.ui.list_pred_analysis_multi_model_chains.selectedItems():
7183            prot_2_chains.append(chain.text())
7184        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7185        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7186        for tmp_row in range(self._view.ui.list_pred_analysis_multi_overview.count()):
7187            if analysis_name == self._view.ui.list_pred_analysis_multi_overview.item(tmp_row).text():
7188                self._view.ui.btn_pred_analysis_multi_next_4.setEnabled(False)
7189                styles.color_button_not_ready(self._view.ui.btn_pred_analysis_multi_next_4)
7190                return

Checks if the same number of chains were selected.

def check_multi_pred_analysis_if_prot_structs_are_filled(self) -> None:
7192    def check_multi_pred_analysis_if_prot_structs_are_filled(self) -> None:
7193        """Checks if two proteins were selected."""
7194        prot_1 = self._view.ui.box_pred_analysis_multi_prot_struct_1.itemText(
7195            self._view.ui.box_pred_analysis_multi_prot_struct_1.currentIndex(),
7196        )
7197        prot_2 = self._view.ui.box_pred_analysis_multi_prot_struct_2.itemText(
7198            self._view.ui.box_pred_analysis_multi_prot_struct_2.currentIndex(),
7199        )
7200        if prot_1 != "" and prot_2 != "":
7201            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(True)
7202        else:
7203            self._view.ui.btn_pred_analysis_multi_next_2.setEnabled(False)

Checks if two proteins were selected.

def count_multi_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
7205    def count_multi_pred_analysis_selected_chains_for_prot_struct_1(self) -> None:
7206        """Counts the number of chains in protein 1."""
7207        self.no_of_selected_chains = len(self._view.ui.list_pred_analysis_multi_ref_chains.selectedItems())
7208        if self.no_of_selected_chains > 0:
7209            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(True)
7210        else:
7211            self._view.ui.btn_pred_analysis_multi_next_3.setEnabled(False)

Counts the number of chains in protein 1.

def structure_analysis_add(self) -> None:
7217    def structure_analysis_add(self) -> None:
7218        """Shows the gui elements to choose the two proteins."""
7219        gui_elements_to_show = [
7220            self._view.ui.lbl_analysis_batch_overview,
7221            self._view.ui.list_analysis_batch_overview,
7222            self._view.ui.lbl_analysis_batch_prot_struct_1,
7223            self._view.ui.box_analysis_batch_prot_struct_1,
7224            self._view.ui.lbl_analysis_batch_vs,
7225            self._view.ui.lbl_analysis_batch_prot_struct_2,
7226            self._view.ui.box_analysis_batch_prot_struct_2,
7227            self._view.ui.btn_analysis_batch_back,
7228            self._view.ui.btn_analysis_batch_next,
7229        ]
7230        gui_elements_to_hide = [
7231            self._view.ui.btn_analysis_batch_remove,
7232            self._view.ui.btn_analysis_batch_add,
7233            self._view.ui.lbl_analysis_batch_ref_chains,
7234            self._view.ui.list_analysis_batch_ref_chains,
7235            self._view.ui.btn_analysis_batch_back_2,
7236            self._view.ui.btn_analysis_batch_next_2,
7237            self._view.ui.lbl_analysis_batch_model_chains,
7238            self._view.ui.list_analysis_batch_model_chains,
7239            self._view.ui.btn_analysis_batch_back_3,
7240            self._view.ui.btn_analysis_batch_next_3,
7241            self._view.ui.lbl_analysis_batch_images,
7242            self._view.ui.cb_analysis_batch_images,
7243            self._view.ui.btn_analysis_batch_start,
7244        ]
7245
7246        gui_utils.show_gui_elements(gui_elements_to_show)
7247        gui_utils.hide_gui_elements(gui_elements_to_hide)
7248        self._view.ui.lbl_analysis_batch_prot_struct_1.clear()
7249        self._view.ui.lbl_analysis_batch_prot_struct_2.clear()
7250        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7251        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")
7252        self.fill_protein_boxes_batch()
7253        if self._view.ui.list_analysis_batch_overview.count() > 0:
7254            try:
7255                self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7256            except AttributeError:
7257                constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")

Shows the gui elements to choose the two proteins.

def structure_analysis_back(self) -> None:
7259    def structure_analysis_back(self) -> None:
7260        """Hides the gui elements to choose the two proteins."""
7261        gui_elements_to_show = [
7262            self._view.ui.lbl_analysis_batch_overview,
7263            self._view.ui.list_analysis_batch_overview,
7264            self._view.ui.btn_analysis_batch_add,
7265        ]
7266        gui_elements_to_hide = [
7267            self._view.ui.btn_analysis_batch_remove,
7268            self._view.ui.lbl_analysis_batch_prot_struct_1,
7269            self._view.ui.lbl_analysis_batch_prot_struct_2,
7270            self._view.ui.lbl_analysis_batch_vs,
7271            self._view.ui.lbl_analysis_batch_ref_chains,
7272            self._view.ui.list_analysis_batch_ref_chains,
7273            self._view.ui.btn_analysis_batch_back_2,
7274            self._view.ui.btn_analysis_batch_next_2,
7275            self._view.ui.box_analysis_batch_prot_struct_1,
7276            self._view.ui.box_analysis_batch_prot_struct_2,
7277            self._view.ui.btn_analysis_batch_back,
7278            self._view.ui.btn_analysis_batch_next,
7279            self._view.ui.lbl_analysis_batch_model_chains,
7280            self._view.ui.list_analysis_batch_model_chains,
7281            self._view.ui.btn_analysis_batch_back_3,
7282            self._view.ui.btn_analysis_batch_next_3,
7283            self._view.ui.lbl_analysis_batch_images,
7284            self._view.ui.cb_analysis_batch_images,
7285            self._view.ui.btn_analysis_batch_start,
7286        ]
7287        gui_utils.show_gui_elements(gui_elements_to_show)
7288        gui_utils.hide_gui_elements(gui_elements_to_hide)
7289        if self._view.ui.list_analysis_batch_overview.count() > 0:
7290            self._view.ui.btn_analysis_batch_remove.show()
7291            self._view.ui.btn_analysis_batch_remove.setEnabled(False)
7292            self._view.ui.btn_analysis_batch_start.show()
7293            self._view.ui.lbl_analysis_batch_images.show()
7294            self._view.ui.cb_analysis_batch_images.show()

Hides the gui elements to choose the two proteins.

def structure_analysis_next_2(self) -> None:
7296    def structure_analysis_next_2(self) -> None:
7297        """Shows the gui elements to select the chains in protein 2."""
7298        gui_elements_to_show = [
7299            self._view.ui.lbl_analysis_batch_overview,
7300            self._view.ui.list_analysis_batch_overview,
7301            self._view.ui.lbl_analysis_batch_prot_struct_1,
7302            self._view.ui.lbl_analysis_batch_prot_struct_2,
7303            self._view.ui.lbl_analysis_batch_vs,
7304            self._view.ui.lbl_analysis_batch_ref_chains,
7305            self._view.ui.list_analysis_batch_ref_chains,
7306            self._view.ui.lbl_analysis_batch_model_chains,
7307            self._view.ui.list_analysis_batch_model_chains,
7308            self._view.ui.btn_analysis_batch_back_3,
7309            self._view.ui.btn_analysis_batch_next_3,
7310        ]
7311        gui_elements_to_hide = [
7312            self._view.ui.btn_analysis_batch_remove,
7313            self._view.ui.btn_analysis_batch_add,
7314            self._view.ui.box_analysis_batch_prot_struct_1,
7315            self._view.ui.box_analysis_batch_prot_struct_2,
7316            self._view.ui.btn_analysis_batch_back,
7317            self._view.ui.btn_analysis_batch_next,
7318            self._view.ui.btn_analysis_batch_back_2,
7319            self._view.ui.btn_analysis_batch_next_2,
7320            self._view.ui.lbl_analysis_batch_images,
7321            self._view.ui.cb_analysis_batch_images,
7322            self._view.ui.btn_analysis_batch_start,
7323        ]
7324        gui_utils.show_gui_elements(gui_elements_to_show)
7325        gui_utils.hide_gui_elements(gui_elements_to_hide)
7326        self._view.ui.list_analysis_batch_model_chains.clear()
7327        self._view.ui.list_analysis_batch_ref_chains.setEnabled(False)
7328        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7329
7330        tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7331        for tmp_chain in tmp_protein.chains:
7332            if tmp_chain.chain_type == "protein_chain":
7333                self._view.ui.list_analysis_batch_model_chains.addItem(tmp_chain.chain_letter)
7334        if len(self._view.ui.list_analysis_batch_ref_chains.selectedItems()) == 1:
7335            self._view.ui.lbl_analysis_batch_model_chains.setText(
7336                f"Select 1 chain in protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7337            )
7338        else:
7339            self._view.ui.lbl_analysis_batch_model_chains.setText(
7340                f"Select {len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())} chains in "
7341                f"protein structure {self._view.ui.lbl_analysis_batch_prot_struct_2.text()}.",
7342            )

Shows the gui elements to select the chains in protein 2.

def structure_analysis_back_2(self) -> None:
7344    def structure_analysis_back_2(self) -> None:
7345        """Hides the gui elements to select the chains in protein 1."""
7346        gui_elements_to_show = [
7347            self._view.ui.lbl_analysis_batch_overview,
7348            self._view.ui.list_analysis_batch_overview,
7349            self._view.ui.lbl_analysis_batch_prot_struct_1,
7350            self._view.ui.box_analysis_batch_prot_struct_1,
7351            self._view.ui.lbl_analysis_batch_vs,
7352            self._view.ui.lbl_analysis_batch_prot_struct_2,
7353            self._view.ui.box_analysis_batch_prot_struct_2,
7354            self._view.ui.btn_analysis_batch_back,
7355            self._view.ui.btn_analysis_batch_next,
7356        ]
7357        gui_elements_to_hide = [
7358            self._view.ui.btn_analysis_batch_remove,
7359            self._view.ui.btn_analysis_batch_add,
7360            self._view.ui.lbl_analysis_batch_ref_chains,
7361            self._view.ui.list_analysis_batch_ref_chains,
7362            self._view.ui.btn_analysis_batch_back_2,
7363            self._view.ui.btn_analysis_batch_next_2,
7364            self._view.ui.lbl_analysis_batch_model_chains,
7365            self._view.ui.list_analysis_batch_model_chains,
7366            self._view.ui.btn_analysis_batch_back_3,
7367            self._view.ui.btn_analysis_batch_next_3,
7368            self._view.ui.lbl_analysis_batch_images,
7369            self._view.ui.cb_analysis_batch_images,
7370            self._view.ui.btn_analysis_batch_start,
7371        ]
7372        gui_utils.show_gui_elements(gui_elements_to_show)
7373        gui_utils.hide_gui_elements(gui_elements_to_hide)
7374        self._view.ui.lbl_analysis_batch_prot_struct_1.setText("Protein structure 1")
7375        self._view.ui.lbl_analysis_batch_prot_struct_2.setText("Protein structure 2")

Hides the gui elements to select the chains in protein 1.

def structure_analysis_next_3(self) -> None:
7377    def structure_analysis_next_3(self) -> None:
7378        """Adds the protein pair to the list of protein pairs to analyze."""
7379        gui_elements_to_show = [
7380            self._view.ui.btn_analysis_batch_remove,
7381            self._view.ui.btn_analysis_batch_add,
7382            self._view.ui.lbl_analysis_batch_overview,
7383            self._view.ui.list_analysis_batch_overview,
7384            self._view.ui.lbl_analysis_batch_images,
7385            self._view.ui.cb_analysis_batch_images,
7386            self._view.ui.btn_analysis_batch_start,
7387        ]
7388        gui_elements_to_hide = [
7389            self._view.ui.box_analysis_batch_prot_struct_1,
7390            self._view.ui.box_analysis_batch_prot_struct_2,
7391            self._view.ui.lbl_analysis_batch_prot_struct_1,
7392            self._view.ui.lbl_analysis_batch_prot_struct_2,
7393            self._view.ui.lbl_analysis_batch_vs,
7394            self._view.ui.lbl_analysis_batch_ref_chains,
7395            self._view.ui.list_analysis_batch_ref_chains,
7396            self._view.ui.lbl_analysis_batch_model_chains,
7397            self._view.ui.list_analysis_batch_model_chains,
7398            self._view.ui.btn_analysis_batch_back,
7399            self._view.ui.btn_analysis_batch_next,
7400            self._view.ui.btn_analysis_batch_back_2,
7401            self._view.ui.btn_analysis_batch_next_2,
7402            self._view.ui.btn_analysis_batch_back_3,
7403            self._view.ui.btn_analysis_batch_next_3,
7404        ]
7405        gui_utils.show_gui_elements(gui_elements_to_show)
7406        gui_utils.hide_gui_elements(gui_elements_to_hide)
7407        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7408        prot_1_chains = []
7409        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7410            prot_1_chains.append(chain.text())
7411        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7412        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7413        prot_2_chains = []
7414        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7415            prot_2_chains.append(chain.text())
7416        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7417        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7418        item = QtWidgets.QListWidgetItem(analysis_name)
7419        self._view.ui.list_analysis_batch_overview.addItem(item)
7420        self._view.ui.btn_analysis_batch_remove.setEnabled(False)

Adds the protein pair to the list of protein pairs to analyze.

def structure_analysis_back_3(self) -> None:
7422    def structure_analysis_back_3(self) -> None:
7423        """Hides the gui elements to select the chains in protein 2."""
7424        gui_elements_to_show = [
7425            self._view.ui.lbl_analysis_batch_overview,
7426            self._view.ui.list_analysis_batch_overview,
7427            self._view.ui.lbl_analysis_batch_prot_struct_1,
7428            self._view.ui.lbl_analysis_batch_prot_struct_2,
7429            self._view.ui.lbl_analysis_batch_vs,
7430            self._view.ui.lbl_analysis_batch_ref_chains,
7431            self._view.ui.list_analysis_batch_ref_chains,
7432            self._view.ui.btn_analysis_batch_back_2,
7433            self._view.ui.btn_analysis_batch_next_2,
7434        ]
7435        gui_elements_to_hide = [
7436            self._view.ui.btn_analysis_batch_remove,
7437            self._view.ui.btn_analysis_batch_add,
7438            self._view.ui.box_analysis_batch_prot_struct_1,
7439            self._view.ui.box_analysis_batch_prot_struct_2,
7440            self._view.ui.btn_analysis_batch_back,
7441            self._view.ui.btn_analysis_batch_next,
7442            self._view.ui.btn_analysis_batch_back_3,
7443            self._view.ui.btn_analysis_batch_next_3,
7444            self._view.ui.lbl_analysis_batch_images,
7445            self._view.ui.cb_analysis_batch_images,
7446            self._view.ui.btn_analysis_batch_start,
7447            self._view.ui.lbl_analysis_batch_model_chains,
7448            self._view.ui.list_analysis_batch_model_chains,
7449        ]
7450        gui_utils.show_gui_elements(gui_elements_to_show)
7451        gui_utils.hide_gui_elements(gui_elements_to_hide)
7452        self._view.ui.list_analysis_batch_ref_chains.setEnabled(True)
7453
7454        # tmp_protein = self._current_project.search_protein(self._view.ui.box_analysis_batch_prot_struct_2.currentText())
7455        # for tmp_chain in tmp_protein.chains:
7456        #     if tmp_chain.chain_type == "protein_chain":
7457        #         self._view.ui.list_analysis_batch_ref_chains.addItem(tmp_chain.chain_letter)

Hides the gui elements to select the chains in protein 2.

def structure_analysis_overview_clicked(self) -> None:
7459    def structure_analysis_overview_clicked(self) -> None:
7460        """Enables the remove button."""
7461        self._view.ui.btn_analysis_batch_remove.setEnabled(True)

Enables the remove button.

def fill_protein_boxes_batch(self) -> None:
7463    def fill_protein_boxes_batch(self) -> None:
7464        """Fills the combo boxes with the protein names."""
7465        proteins = []
7466        for tmp_protein in self._current_project.proteins:
7467            proteins.append(tmp_protein.get_molecule_object())
7468        proteins.insert(0, "")
7469        self._view.ui.box_analysis_batch_prot_struct_1.clear()
7470        self._view.ui.box_analysis_batch_prot_struct_2.clear()
7471        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_1, proteins)
7472        gui_utils.fill_combo_box(self._view.ui.box_analysis_batch_prot_struct_2, proteins)

Fills the combo boxes with the protein names.

def remove_analysis_run(self) -> None:
7474    def remove_analysis_run(self) -> None:
7475        """Removes the selected protein pair from the list of protein pairs to analyze."""
7476        self._view.ui.list_analysis_batch_overview.takeItem(self._view.ui.list_analysis_batch_overview.currentRow())
7477        if self._view.ui.list_analysis_batch_overview.count() == 0:
7478            gui_elements_to_show = [
7479                self._view.ui.lbl_analysis_batch_overview,
7480                self._view.ui.list_analysis_batch_overview,
7481                self._view.ui.btn_analysis_batch_add,
7482            ]
7483
7484            gui_elements_to_hide = [
7485                self._view.ui.btn_analysis_batch_remove,
7486                self._view.ui.lbl_analysis_batch_prot_struct_1,
7487                self._view.ui.lbl_analysis_batch_prot_struct_2,
7488                self._view.ui.lbl_analysis_batch_vs,
7489                self._view.ui.lbl_analysis_batch_ref_chains,
7490                self._view.ui.list_analysis_batch_ref_chains,
7491                self._view.ui.btn_analysis_batch_back_2,
7492                self._view.ui.btn_analysis_batch_next_2,
7493                self._view.ui.box_analysis_batch_prot_struct_1,
7494                self._view.ui.box_analysis_batch_prot_struct_2,
7495                self._view.ui.btn_analysis_batch_back,
7496                self._view.ui.btn_analysis_batch_next,
7497                self._view.ui.lbl_analysis_batch_model_chains,
7498                self._view.ui.list_analysis_batch_model_chains,
7499                self._view.ui.btn_analysis_batch_back_3,
7500                self._view.ui.btn_analysis_batch_next_3,
7501                self._view.ui.lbl_analysis_batch_images,
7502                self._view.ui.cb_analysis_batch_images,
7503                self._view.ui.btn_analysis_batch_start,
7504            ]
7505
7506            gui_utils.show_gui_elements(gui_elements_to_show)
7507            gui_utils.hide_gui_elements(gui_elements_to_hide)
7508            self._view.ui.btn_analysis_batch_remove.hide()
7509        else:
7510            if self._view.ui.list_analysis_batch_overview.count() > 0:
7511                try:
7512                    self._view.ui.list_analysis_batch_overview.currentItem().setSelected(False)
7513                except AttributeError:
7514                    constants.PYSSA_LOGGER.debug("No selection in struction analysis overview.")
7515        self._view.ui.btn_analysis_batch_remove.setEnabled(False)

Removes the selected protein pair from the list of protein pairs to analyze.

def check_if_same_no_of_chains_selected_batch(self) -> None:
7517    def check_if_same_no_of_chains_selected_batch(self) -> None:
7518        """Checks if the same number of proteins were selected."""
7519        self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7520        if self.no_of_selected_chains == len(self._view.ui.list_analysis_batch_model_chains.selectedItems()):
7521            self._view.ui.btn_analysis_batch_next_3.setEnabled(True)
7522
7523        prot_1_name = self._view.ui.lbl_analysis_batch_prot_struct_1.text()
7524        prot_1_chains = []
7525        for chain in self._view.ui.list_analysis_batch_ref_chains.selectedItems():
7526            prot_1_chains.append(chain.text())
7527        prot_1_chains = ",".join([str(elem) for elem in prot_1_chains])
7528        prot_2_name = self._view.ui.lbl_analysis_batch_prot_struct_2.text()
7529        prot_2_chains = []
7530        for chain in self._view.ui.list_analysis_batch_model_chains.selectedItems():
7531            prot_2_chains.append(chain.text())
7532        prot_2_chains = ",".join([str(elem) for elem in prot_2_chains])
7533        analysis_name = f"{prot_1_name};{prot_1_chains}_vs_{prot_2_name};{prot_2_chains}"
7534        for tmp_row in range(self._view.ui.list_analysis_batch_overview.count()):
7535            if analysis_name == self._view.ui.list_analysis_batch_overview.item(tmp_row).text():
7536                self._view.ui.btn_analysis_batch_next_3.setEnabled(False)
7537                styles.color_button_not_ready(self._view.ui.btn_analysis_batch_next_3)
7538                return

Checks if the same number of proteins were selected.

def check_if_prot_structs_are_filled_batch(self) -> None:
7540    def check_if_prot_structs_are_filled_batch(self) -> None:
7541        """Checks if two proteins were selected."""
7542        prot_1 = self._view.ui.box_analysis_batch_prot_struct_1.itemText(
7543            self._view.ui.box_analysis_batch_prot_struct_1.currentIndex(),
7544        )
7545        prot_2 = self._view.ui.box_analysis_batch_prot_struct_2.itemText(
7546            self._view.ui.box_analysis_batch_prot_struct_2.currentIndex(),
7547        )
7548        if prot_1 != "" and prot_2 != "":
7549            self._view.ui.btn_analysis_batch_next.setEnabled(True)
7550        else:
7551            self._view.ui.btn_analysis_batch_next.setEnabled(False)

Checks if two proteins were selected.

def count_batch_selected_chains_for_prot_struct_1(self) -> None:
7553    def count_batch_selected_chains_for_prot_struct_1(self) -> None:
7554        """Counts the number of chains of protein 1."""
7555        self.no_of_selected_chains = len(self._view.ui.list_analysis_batch_ref_chains.selectedItems())
7556        if self.no_of_selected_chains > 0:
7557            self._view.ui.btn_analysis_batch_next_2.setEnabled(True)
7558        else:
7559            self._view.ui.btn_analysis_batch_next_2.setEnabled(False)

Counts the number of chains of protein 1.

def display_image_analysis_page(self) -> None:
7564    def display_image_analysis_page(self) -> None:
7565        """Displays the analysis image work area."""
7566        # get all protein pairs without images
7567        self._view.ui.list_analysis_images_struct_analysis.clear()
7568        self._view.ui.list_analysis_images_creation_struct_analysis.clear()
7569        for tmp_protein_pair in self._current_project.protein_pairs:
7570            if len(tmp_protein_pair.distance_analysis.analysis_results.structure_aln_image) == 0:
7571                self._view.ui.list_analysis_images_struct_analysis.addItem(tmp_protein_pair.name)
7572        self.last_sidebar_button = styles.color_sidebar_buttons(
7573            self.last_sidebar_button,
7574            self._view.ui.btn_image_analysis_page,
7575        )
7576        tools.switch_page(self._view.ui.stackedWidget, self._view.ui.lbl_page_title, 23, "Analysis Images")
7577        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7578        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7579        self._view.ui.btn_start_automatic_image_creation.setEnabled(False)

Displays the analysis image work area.

def analysis_images_enable_add(self) -> None:
7581    def analysis_images_enable_add(self) -> None:
7582        """Enables the add button."""
7583        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(True)

Enables the add button.

def analysis_images_enable_remove(self) -> None:
7585    def analysis_images_enable_remove(self) -> None:
7586        """Enables the remove button."""
7587        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(True)

Enables the remove button.

def add_protein_pair_to_image_creation_queue(self) -> None:
7589    def add_protein_pair_to_image_creation_queue(self) -> None:
7590        """Adds a protein pair from the list of protein pairs to make images of."""
7591        protein_pair_to_add = self._view.ui.list_analysis_images_struct_analysis.currentItem().text()
7592        self._view.ui.list_analysis_images_creation_struct_analysis.addItem(protein_pair_to_add)
7593        self._view.ui.list_analysis_images_struct_analysis.takeItem(
7594            self._view.ui.list_analysis_images_struct_analysis.currentRow(),
7595        )
7596        self._view.ui.btn_add_analysis_images_struct_analysis.setEnabled(False)
7597        self.analysis_images_check_if_creation_can_start()

Adds a protein pair from the list of protein pairs to make images of.

def remove_protein_pair_from_image_creation_queue(self) -> None:
7599    def remove_protein_pair_from_image_creation_queue(self) -> None:
7600        """Removes a protein pair from the list of protein pairs to make images of."""
7601        protein_pair_to_remove = self._view.ui.list_analysis_images_creation_struct_analysis.currentItem()
7602        self._view.ui.list_analysis_images_creation_struct_analysis.takeItem(
7603            self._view.ui.list_analysis_images_creation_struct_analysis.currentRow(),
7604        )
7605        self._view.ui.list_analysis_images_struct_analysis.addItem(protein_pair_to_remove)
7606        self._view.ui.btn_remove_analysis_images_creation_struct_analysis.setEnabled(False)
7607        self.analysis_images_check_if_creation_can_start()

Removes a protein pair from the list of protein pairs to make images of.

def analysis_images_check_if_creation_can_start(self) -> None:
7609    def analysis_images_check_if_creation_can_start(self) -> None:
7610        """Checks if the list of protein pairs which get images are empty."""
7611        if self._view.ui.list_analysis_images_creation_struct_analysis.count() > 0:
7612            self._view.ui.btn_start_automatic_image_creation.setEnabled(True)
7613        else:
7614            self._view.ui.btn_start_automatic_image_creation.setEnabled(False)

Checks if the list of protein pairs which get images are empty.

def update_status(self, message: str) -> None:
7620    def update_status(self, message: str) -> None:
7621        """Updates the status bar of the main view with a custom message."""
7622        self._view.status_bar.showMessage(message)

Updates the status bar of the main view with a custom message.